13

I am using Python, and I have a function which takes a list as the argument. For example, I am using the following syntax,

def square(x,result= []):
    for y in x:
        result.append=math.pow(y,2.0)
        return result

print(square([1,2,3]))

and the output is [1] only where I am supposed to get [1,4,9].

What am I doing wrong?

8
  • 14
    1. Don't make mutable default arguments. 2. You can only return once. Commented Jan 31, 2016 at 23:04
  • 1
    Then how can I return an array as the output. Can you give me any idea? Thank you Commented Jan 31, 2016 at 23:05
  • 3
    Bring the return out of the for loop. Commented Jan 31, 2016 at 23:05
  • 10
    @MaSH please don't recommend bad practices like that. There's no reason to use globals here. Commented Jan 31, 2016 at 23:24
  • 2
    Based on your comments it seems the answers here have resolved the issue. The SO culture encourages you to mark the answer that has solved your problem as the accepted one. However, this isn't mandatory. Commented Feb 1, 2016 at 1:22

7 Answers 7

21

Why not side-step the problem altogether?

def square(vals):
    return [v*v for v in vals]

Edit: The first problem, as several people have pointed out, is that you are short-circuiting your for loop. Your return should come after the loop, not in it.

The next problem is your use of list.append - you need to call it, not assign to it, ie result.append(y*y). result.append = y*y instead overwrites the method with a numeric value, probably throwing an error the next time you try to call it.

Once you fix that, you will find another less obvious error occurs if you call your function repeatedly:

print(square([1,2,3])     # => [1, 4, 9]
print(square([1,2,3])     # => [1, 4, 9, 1, 4, 9]

Because you pass a mutable item (a list) as a default, all further use of that default item points back to the same original list.

Instead, try

def square(vals, result=None):
    if result is None:
        result = []
    result.extend(v*v for v in vals)
    return result
Sign up to request clarification or add additional context in comments.

4 Comments

This doesn't really tell the OP where they are going wrong and is just a one liner of how to square an array
@ShaneQful: please take another look.
Apologies, my initial comment above was based on your initial succinct answer. Have an up vote :)
this is the only answer that even mentions the mistaken assignment to result.append, which is an error in all situations.
16

You are currently returning a value from your function in the first iteration of your for loop. Because of this, the second and third iteration of your for loop never take place. You need to move your return statement outside of the loop as follows:

import math

def square(x):
    result = []
    for y in x:
        result.append(math.pow(y,2.0))
    return result 

print(square([1,2,3]))

Output

[1.0, 4.0, 9.0]

2 Comments

As someone used to brace based programming rather than indentation based, I must say that single tab changing where the function returns from is something I find horribly unintuitive.
But you still indent your code even if your using braces, don't you?
6

We even use result? You can use a list comprehension to generate your result which you then return. I'm not sure why you passed result as a variable into the function, since it is not used.

Also, having return result inside your loop means the function returns the value on the first iteration, so it just returns the square of the first number in the list.

import math

def square(x):
    return [math.pow(y, 2) for y in x]

>>> print(square([1,2,3]))
[1.0, 4.0, 9.0]

1 Comment

Well, it could be seen as the initial value, for example. Perhaps OP intended square([1,2,3],[100,200,300]) to return [100,200,300,1,4,9].
3

You might be interested in using yield

def square(x):
    for y in x:
        yield math.pow(y, 2.0)

that way you can either call

for sq in square(x):
    ...

which won't generate the entire list of squares at once but rather one element per iteration, or use list(square(x)) to obtain the full list on demand.

Comments

3

This is a fun opportunity to use a slightly more functional style:

import math
map(lambda x:(math.pow(x,2)), [1,2,3])

This uses the map function, which takes a list and a function, and returns a new list where that function has been applied individually to each member of the list. In this case, it applies the math.pow(x,2) function to each member of the list, where each number is x.

Notice that map(lambda x:(math.pow(x,2)), [1,2,3]) returns an iterable, which is really convenient, but if you need to get a list back just wrap the entire statement in list().

Comments

3

You should return outside the for loop. Otherwise, it will stop after first iteration.

def square(x):
    result=[]
    for y in x:
        result.append(math.pow(y,2.0)) # add to list after calculation
    return result 

print(square([1,2,3])

1 Comment

Append is a function you don't want to overwrite here.
0

your code doesn't make sense anywhere. syntax error at the end missing the closing bracket for the print, return call inside the for loop meaning it only executes once, and result.append is a function not a constructor sp the correct call is

result.append(math.pow(y,2))

the only thing that is not an issue is the passing of the list which is your question, the function is receiving the whole list if you do

def f(a):
    print a
f([1,2,3])

out

[1,2,3,]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.