0

I am analyzing the following code sample:

>>> def check(v):
...     for t in v:
...             yield t
...             if t==2:
...                     yield "a"

Do I understand correctly that the two last lines of code will never be executed, because yield works as return. So, basically the first yield in a for loop (before the if clause) will always be applied.

Is my understanding correct?

UPDATE:

I do not understand why do I get the sequence 2, a, 2, a, 1, ... and not this one: 1,a,1,...

>>> my_list = [2,2,1,2,3]
>>> f = check(my_list)
>>> f.next()
2
>>> f.next()
'a'
>>> f.next()
2
>>> f.next()
'a'
>>> f.next()
1
>>> f.next()
2
Dinosaurius
  • 8,306
  • 19
  • 64
  • 113
  • 1
    This is called generators. Shameless plug: read my [blog post](http://rahmonov.me/posts/python-generators/) about them :) – Jahongir Rahmonov Oct 03 '17 at 19:09
  • 2
    *"`yield` works as `return`"* - No, `return` works as `return`. There's no reason to have two different `return` by two different names. Why would the second one make more sense; it's a "`return`" in a loop, which would also be rather pointless. – deceze Oct 03 '17 at 19:09
  • No, `yield` is not the same as `return` – juanpa.arrivillaga Oct 03 '17 at 19:12
  • @JahongirRahmonov: I read your post, thanks. I understand the difference between `yield` and `return`. However, what I do not understand is if the `if` will ever be executed in my first code sample. – Dinosaurius Oct 03 '17 at 19:15
  • I will try to explain generators with an example using the same algorithm: try in console: `>>>f = check("some value")` them to get yield one by one you can run: `>>>f.__next__()` – Manu Oct 03 '17 at 19:15
  • 1
    Yes it will. And @DanielHeidemann that is incorrect. calling `check` again *creates a new generator*. You mean calling `next(gen_object)` on the generator object *returned by `check`* – juanpa.arrivillaga Oct 03 '17 at 19:16
  • In short: yes, the `if` *will* be executed (*if* something is reading from the generator…). – deceze Oct 03 '17 at 19:16
  • @Dinosaurius Upd: sorry, I am mistaken. Yes, it will be execured – Jahongir Rahmonov Oct 03 '17 at 19:16
  • @DanielHeidemann: So, do you want to say that the first `yield` will be executed when the function `check` is called the first time, and then in the next calls `if` will be executed? Could you put some relevant example? – Dinosaurius Oct 03 '17 at 19:17
  • @Dinosaurius that's the beauty of `generators`, it will give you the control back after `yielding` and then will continue where it left off – Jahongir Rahmonov Oct 03 '17 at 19:18
  • @juanpa.arrivillaga Thanks for pointing it out. I was a bit unclear. I was thinking of for c in check(). I have removed the comment to avoid confusion. – Daniel Heidemann Oct 03 '17 at 19:19
  • @Manu: I get the error `AttributeError: 'generator' object has no attribute '__next__'`. – Dinosaurius Oct 03 '17 at 19:21
  • @Dinosaurius because you are on Python 2, so the method is `.next`. Do yourself a favor, get on Python 3. But in either case, use the built-in function `next` not the method directly – juanpa.arrivillaga Oct 03 '17 at 19:22
  • So, I appreciate if someone could post the step-by-step explanation of my example. I am still very confused and my tests from command line did not help me better understand `yield` for my particular case. – Dinosaurius Oct 03 '17 at 19:23
  • @Dinosaurius go read about generators. Read the posted duplicate, which is one of the most up-voted questions on stack overflow. Use Python 3, and make sure you are reading about Python 3, since the iterator protocol changed. – juanpa.arrivillaga Oct 03 '17 at 19:24
  • @juanpa.arrivillaga: I switched to Python 3. I do not understand why I get 2, a,2,a,1,2,a,3 for my posted example. I understand the first value, but the second one is meaningless. And yes, I read the post that you referenced. – Dinosaurius Oct 03 '17 at 19:31
  • Because you yield the number you are iterating over, then if the number is equal to `2`, you yield `'a'`... what don't you understand? – juanpa.arrivillaga Oct 03 '17 at 19:39
  • @Dinosaurius in python 2 you need first write at the begining of code `from __future__ import generators` let me know how it was? – Manu Oct 04 '17 at 13:00

0 Answers0