[Python-Dev] Tricky way of of creating a generator via a comprehension expression

Nick Coghlan ncoghlan at gmail.com
Sat Nov 25 02:10:12 EST 2017


On 25 November 2017 at 16:18, Nathaniel Smith <njs at pobox.com> wrote:
> On Fri, Nov 24, 2017 at 9:39 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On 25 November 2017 at 15:27, Nathaniel Smith <njs at pobox.com> wrote:
>>> On Fri, Nov 24, 2017 at 9:04 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>>>     def example():
>>>>         comp1 = yield from [(yield x) for x in ('1st', '2nd')]
>>>>         comp2 = yield from [(yield x) for x in ('3rd', '4th')]
>>>>         return comp1, comp2
>>>
>>> Isn't this a really confusing way of writing
>>>
>>> def example():
>>>     return [(yield '1st'), (yield '2nd')], [(yield '3rd'), (yield '4th')]
>>
>> A real use case
>
> Do you have a real use case? This seems incredibly niche...

That's not how backwards compatibility works - we were suggesting
getting rid of this syntax, because there was no current way to make
it do anything sensible.

It turns out there is a way to make it behave reasonably - you just
need to stick "yield from" in front of it, and it goes back to being
equivalent to the corresponding for loop (the same as the synchronous
version).

>> wouldn't be iterating over hardcoded tuples in the
>> comprehensions, it would be something more like:
>>
>>     def example(iterable1, iterable2):
>>         comp1 = yield from [(yield x) for x in iterable1]
>>         comp2 = yield from [(yield x) for x in iterable2]
>>         return comp1, comp2
>
> I submit that this would still be easier to understand if written out like:
>
> def map_iterable_to_yield_values(iterable):
>     "Yield the values in iterable, then return a list of the values sent back."
>     result = []
>     for obj in iterable:
>         result.append(yield obj)
>     return result
>
> def example(iterable1, iterable2):
>     values1 = yield from map_iterable_to_yield_values(iterable1)
>     values2 = yield from map_iterable_to_yield_values(iterable2)
>     return values1, values2

The same can be said for comprehensions in general. Composing them
with coroutines certainly doesn't make either easier to understand,
but I don't think replacing the comprehension with its full imperative
form is particularly helpful in aiding that understanding.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list