标签云

微信群

扫码加入我们

WeChat QR Code

What is the use of the yield keyword in Python? What does it do?For example, I'm trying to understand this code1:def _get_child_candidates(self, distance, min_dist, max_dist):if self._leftchild and distance - max_dist < self._median:yield self._leftchildif self._rightchild and distance + max_dist >= self._median:yield self._rightchildAnd this is the caller:result, candidates = [], [self]while candidates:node = candidates.pop()distance = node._get_dist(obj)if distance <= max_dist and distance >= min_dist:result.extend(node._values)candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))return resultWhat happens when the method _get_child_candidates is called?Is a list returned? A single element? Is it called again? When will subsequent calls stop?1. This piece of code was written by Jochen Schulz (jrschulz), who made a great Python library for metric spaces. This is the link to the complete source: Module mspace.


All iterators can only be iterated over once, not just those produced by generator functions.If you don't believe me, call iter() on any iterable object and try to iterate over the result more than once.

2019年06月21日04分57秒

Craicerjack You have your terms mixed up.An iterable is something with an __iter__ method.An iterator is the result of calling iter() on an iterable.Iterators can only be iterated over once.

2019年06月21日04分57秒

yield is not as magical this answer suggests. When you call a function that contains a yield statement anywhere, you get a generator object, but no code runs. Then each time you extract an object from the generator, Python executes code in the function until it comes to a yield statement, then pauses and delivers the object. When you extract another object, Python resumes just after the yield and continues until it reaches another yield (often the same one, but one iteration later). This continues until the function runs off the end, at which point the generator is deemed exhausted.

2019年06月20日04分57秒

"These iterables are handy... but you store all the values in memory and this is not always what you want", is either wrong or confusing. An iterable returns an iterator upon calling the iter() on the iterable, and an iterator doesn't always have to store its values in memory, depending on the implementation of the iter method, it can also generate values in the sequence on demand.

2019年06月21日04分57秒

"When you see a function with yield statements, apply this easy trick to understand what will happen" Doesn't this completely ignore the fact that you can send into a generator, which is a huge part of the point of generators?

2019年06月21日04分57秒

"it could be a for loop, but it could also be code like otherlist.extend(mylist)" -> This is incorrect. extend() modifies the list in-place and does not return an iterable. Trying to loop over otherlist.extend(mylist) will fail with a TypeError because extend() implicitly returns None, and you can't loop over None.

2019年06月21日04分57秒

pedro You have misunderstood that sentence. It means that python performs the two mentioned steps on mylist (not on otherlist) when executing otherlist.extend(mylist).

2019年06月21日04分57秒

__getitem__ could be defined instead of __iter__. For example: class it: pass; it.__getitem__ = lambda self, i: i*10 if i < 10 else [][0]; for i in it(): print(i), It will print: 0, 10, 20, ..., 90

2019年06月21日04分57秒

I tried this example in Python 3.6 and if I create iterator = some_function(), the variable iterator does not have a function called next() anymore, but only a __next__() function. Thought I'd mention it.

2019年06月21日04分57秒

This is close, but not correct.Every time you call a function with a yield statement in it, it returns a brand new generator object.It's only when you call that generator's .next() method that execution resumes after the last yield.

2019年06月21日04分57秒

Just a note - in Python 3, range also returns a generator instead of a list, so you'd also see a similar idea, except that __repr__/__str__ are overridden to show a nicer result, in this case range(1, 10, 2).

2019年06月21日04分57秒

Cute! A trampoline (in the Lisp sense). Not often one sees those!

2019年06月21日04分57秒

This is understandable, but one major difference is that you can have multiple yields in a function/method. The analogy totally breaks down at that point. Yield remembers its place in a function, so the next time you call next(), your function continues on to the next yield. This is important, I think, and should be expressed.

2019年06月21日04分57秒

Don't forget that 2 is prime :-)

2019年06月21日04分57秒

You are correct. But what is the effect on flow which is to see the behaviour of "yield" ? I can change the algorithm in the name of mathmatics. Will it help to get different assessment of "yield" ?

2019年06月21日04分57秒