Jackie
Jackie

Reputation: 57

TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'

I'm trying to take the values from the previous function and use in another function. This is my first programming class and language, and i'm totally lost. I figured out how to take the variables from astlist and put them into the function distance, but now Python is telling me I can't use these variables in an equation because they're in a list now? Is that what it's saying? I'm also just printing the lists to see if they are running. These are two of my functions, and the functions are both defined in my main function. I'm taking these lists and eventually putting them into files, but I need to figure out why the equation isn't working first. Thanks!

def readast():

    astlist = []
    for j in range(15):
        list1 = []

    for i in range(3):
        x = random.randint(1,1000)
        y = random.randint(1,1000)
        z = random.randint(1,1000)
        list1.append([x,y,z])
        astlist.append(list1)
    print(astlist)
    return astlist

def distance(astlist):

    distlist = []
    for row in range(len(astlist)):
        x, y, z = astlist[row]
        x1 = x**2
        y2 = y**2
        z2 = z**2
        equation = math.sqrt(x+y+z)
        distlist.append(equation)
        print(distlist)
        return distlist

Upvotes: 4

Views: 42116

Answers (3)

Jose Reyes
Jose Reyes

Reputation: 41

I will refer to the specific type error (TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'), for some reason arrays are iterable objects for operations like addition: sum(array), but, power: array**2, pow(array,2). You can solve this with some extra steps as follow:

x1 = [j**2 for j in x]

also I recommend to use sum function

sum(x,y,z)

remember all this is to avoid the error message that you were referring to

that way you apply the power of 2 to each element in the array, getting a new array and avoiding the error message that you were asking help for. It seems to me that you are looking to get a normalization of your data using norm L2, if that is true, well, I think you are missing half of it.

Upvotes: 1

Danny
Danny

Reputation: 144

There are a few problems here: Firstly the loop at the top of readast() sets list1 to [] 15 times - I'm not sure what you're trying to do here. If you are trying to generate 15 sets of x,y,z coordinates then it is the second range - in your example the range(3) - that you need to change.

Then you keep adding lists of [x,y,z] to (the same) list1, then adding the whole of list1 to astlist. However, Python actually stores a pointer to the list rather than a copy so when you add items to list1, it adds items to list1 whereever list1 is included in another list: In this example the random numbers are replaced with sequential numbers for clarity (the first random number is 1, the second 2 and so on):

After first cycle of loop:

list1: [[1,2,3]]
astlist: [[[1,2,3]]]

After second cycle of loop:

list1: [[1,2,3],[4,5,6]]
astlist: [[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]]

and so on

As you can see, list1 is now a list of lists, and astlist is now a list of duplicates of list1 (a list of lists of lists)

list1 is probably redundant and you probably want just

astlist.append([x,y,z])

in the first bit.

In the second function, you use

for row in range(len(astlist)):
   x,y,z=astlist[row]
   ...

but actually the following would be better:

for row in astlist:
   x,y,z=row
   ...

or even:

for x,y,z in astlist:
   ...

as for loops in Python iterate over members of a sequence (or other iterable value) rather being just a simple counter. What you are doing with the range(len(astlist)) construct is actually generating a list [1,2,3...] and iterating over that.

If you particularly need a numerical index then you can use the enumerate function which returns a series of (index,value) pairs that you can iterate over thus:

for i,value in enumerate(['apple','banana','cherry']):
    print 'value {} is {}'.format(i,value)


 value 0 is apple
 value 1 is ball
 value 2 is cherry

Hope this helps

Upvotes: 3

Simeon Visser
Simeon Visser

Reputation: 122376

The variable astlist is a list. You're adding list1 to it several times which is also a list. But you're also adding a list to list1 each time: list1.append([x,y,z]). So ultimately astlist is a list containing multiple lists which each contain a list with three integers.

So when you write x,y,z=astlist[row] the variables x, y and z are actually lists, not integers. This means you're trying to compute x**2 but x is a list, not a number. This is why Python is giving you an error message as ** doesn't support raising a list to a power.

I'm not sure what you're trying to accomplish with all these lists but you should change the code so that you're only trying to raise numbers to the power of two and not lists.

Upvotes: 4

Related Questions