Мне нравится использовать следующую идиому для объединения списков, иногда:
>>> list(itertools.chain(*[[(e, n) for e in l] for n, l in (('a', [1,2]),('b',[3,4]))]))
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]
(Я знаю, что есть более простые способы получить этот конкретный результат, но он пригодится, когда вы хотите перебрать элементы в списках списков списков или что-то в этом роде. Проблема в том, что при использовании генератора выражения, это становится склонным к ошибкам. Например,
>>> list(itertools.chain(*(((e, n) for e in l) for n, l in (('a', [1,2]),('b',[3,4])))))
[(1, 'b'), (2, 'b'), (3, 'b'), (4, 'b')]
Здесь происходит то, что выражения внутреннего генератора передаются в качестве аргументов itertools.chain
, поэтому во время их вычисления выражение внешнего генератора завершено, и n
фиксируется в своем окончательном значении, 'b'
. Мне интересно, думал ли кто-нибудь о способах избежать такого рода ошибок, кроме как "не делай этого".