Ответ 1
Это выражение похоже на способ написания кода-гольфа:
(a for b in g for a in b)
((Или, может быть, мотивация заключается в использовании делегаций генераторов, но IMHO-читаемость действительно страдает.))
Например:
#! /usr/bin/python3.3
g = ['abc', 'def', 'ghi']
a = (None for g in g if (yield from g) and False)
for x in a: print (x)
b = (a for b in g for a in b)
for x in b: print (x)
Печать дважды в сплющенном списке.
Я думаю, что он становится более разборчивым, если вы используете разные имена переменных:
(None for sublist in g if (yield from sublist) and False)
То же, что и
(42 for sublist in g if (yield from sublist) and False)
поскольку из-за something and False
внешний генератор ничего не дает, в то время как внутренний генератор дает все элементы всех подписок (подгенераторы, субэлементы).
Возможно, это немного разъясняет, как это работает:
('Sublist {}'.format(idx) for idx, sublist in enumerate(g) if (yield from sublist) or True)
По-видимому, исходный генератор может быть упрощен до этого, опуская последний and False
:
(None for sublist in g if (yield from sublist) )
Revision:
Благодаря Martijn Pieters, сражающемуся с моим упрямством, мне удалось увидеть, что (None for sublist in g if (yield from sublist) and False)
и (None for sublist in g if (yield from sublist) )
не эквивалентны. Вот пример g
, который делает разницу:
def f():
yield 1
return 2
def g():
yield f()
a = (None for sublist in g() if (yield from sublist) )
for x in a: print(x)
a = (None for sublist in g() if (yield from sublist) and False)
for x in a: print(x)
Отпечатки:
1
None
1