3

I have simple program that I am using to understand how generators/yeild works.

def learn_yield(numbers):
    for i in numbers:
        yield (i*i)

numbers = [5]

sq = learn_yield(numbers)

numbers.append(6)

for i in sq:
    print (i)

Here's where my understanding is unclear:

The append method is called after the call to the learn_yield function. I would have expected the output of print(i) as 25 and not

25 36

How exactly did the number 6 get sent to the function?

If I move numbers.append(6) to after the for loop, then I get the behavior I think should happen in the first place. Does this mean that the call to the function is made again when the loop is iterating?

System - PC, Windows 10 Python - 3.7 Sublime Text

1 Answer 1

2

What happens is that learn_yield retains a reference to numbers. When you append to numbers, all code that has a reference to it will see the change.

Put another way, numbers in the function and numbers in the main code are the same object.

If you want to sever that link, you could make learn_yield iterate over a copy:

def learn_yield(numbers):
    for i in numbers[:]:   # [:] makes a copy
        yield (i*i)

For a detailed discussion of how arguments are passed in Python, see How do I pass a variable by reference?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Can you also share as to why this does not apply when we move the numbers.append to after the for loop. Why does that break the reference to numbers?
@HectorM: It does not. What happens in that case is that the number is only appended after learn_yield has finished iterating and so it never sees the 6.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.