List not returning the proper values as an output

Viewed 98

I am trying to write a small function (as an exercise). This function takes a list of values and returns the values that are odd numbers. I have gotten the function to give me the right answer with the print() function, but I am not able to do the same with a return statement.

def odd_nr(list1):
    i = 0
    for list1[i] in list1:
        if list1[i] % 2 != 0:
            print(list1[i])
            i += 1
    return list1

odd_nr([1,2,3,4,5,6])

The output is:

1
3
5
[1, 3, 5, 6, 5, 6]

I am not able to figure out why the return statement gives this output. I tried different indentations, I tried different variants of the return statement, but I just can't seem to get it to work.

What am I doing wrong?

2 Answers

try:

def odd_nr(list1):
    results = []
    for number in list1:
        if number % 2 != 0:
            print(number)
            results.append(number)
    return results

odd_nr([1,2,3,4,5,6])

Further Explanation:

Any function can take something and return something. This something can also be nothing, None.

Your function takes a list, and returns a list, but it is returning the same list that it is taking in.

The print statement is not a return value. Which means a print is not something that the function returns, it is a side-effect, a side door, for us humans to see, mostly.

To return a list of only odd numbers, you need to collect them in another list as you iterate through your original input list.

Then once you are done, return the list that has collected all the odd numbers. Hope this helps.

I also updated your code a bit, for list1[i] in list1, even though it works, it is hard to understand and it does so for the wrong reasons, see below. You can simply do for number in list1 and also not worry about incrementing any counters(i in your case).

Explanation on why for list1[i] in list works:

This is interesting. By choosing list1[i] as the current iteratee, we will be mutating our list while iterating; it is lucky that each iteratee is equal, in value to the list element it is mutating. Here is an example to illustrate what is happening. It is easy to see when we do not update i:

list1= [1,2,3,4]
i=0
for list1[i] in list1:
    print(list1[i])
print(list1)

Output:

1
2
3
4
[4, 2, 3, 4]

You just need to return list1[:i] instead of returning the whole list1. Demo with that:

>>> odd_nr([1,2,3,4,5,6])
1
3
5
[1, 3, 5]

With your unusual but correct for list1[i] in list1 and the according update of i, you're moving all the odd numbers to the front of the list and counting them with i. All that's left to do is to only return that front portion.

Alternatively, delete the unwanted back portion with del list1[i:] before you do return list1.

Related