Your function design is almost right. As others have noted before me, the function you have created returns from the function call after a single odd number is found in the list. One way to get the behavior you desire is to build the list within the function and return that list after the loop over elements completes, as the other respondents have suggested. But there is a way to keep this function in nearly the same form and get the results you want:
Generators
In python, you can create functions that keep track of their internal state. This means you can create a function-like object that takes a list, like your only_odd_numbers
function, but that returns the next odd number in the list every time you call it. These things are called "generators".
You create generators just like you create functions, but instead of "returning" a value, generators "yield" a value, like so:
def only_odd_numbers(s):
for num in s:
if num % 2 != 0:
yield num
Now when you call only_odd_numbers(s)
, it will return a generator rather than a number or a list. You can iterate over that generator just like how you iterate over a list, meaning you can build your answer from a list constructor or list comprehension, like so:
# list constructor
assert list(only_odd_numbers([1, 2, 3])) == [1, 3]
# list comprehension
assert [x for x in only_odd_numbers([-5, -4, -3, -2, -1, 1, 2, 3, 4, 5])] == [-5, -3, -1, 1, 3, 5]
# plain old iteration
itr = only_odd_numbers([-4, -3, 1])
assert next(itr) == -3
assert next(itr) == 1
# no more!
try:
next(itr)
print("Still iterating")
except StopIteration:
print("No more")
I encourage you to read https://stackoverflow.com/a/231855/5075720 to get a better understanding of how generators work and how useful they can be.