Python: давать элементы Dict в генераторах? - PullRequest
17 голосов
/ 16 июля 2011

Прежде чем я скажу слово, позвольте мне поблагодарить сообщество за то, что в последнее время было авторитетным местом для моих запросов программирования.И притворяться, что эти комплименты не были выражены словами.Как бы то ни было, закон вероятности диктовал, что я наткнулся на то, что не смог найти с помощью универсальной панели поиска, поэтому я решил явно спросить впервые.Может быть, я просто не искал, используя достаточно Pythonic-жаргон.Или, может быть, я сосу на Googling / Stackoverflowing.Независимо от того ...

Я играю с сопрограммами и генераторами Python.Из того, что я могу собрать, вы можете сделать все, что может понять генератор, с сопрограммами продюсера, хотя и более многословно.В настоящее время я использую Python 3, хотя любые ответы, касающиеся Python 2, также не будут пропущены.

Поэтому я предполагаю, что следующие фрагменты кода эквивалентны:

one_to_three = (num for num in range(1, 4))

...

def one_to_three():
    for num in range(1, 4):
        yield num

one_to_three_gen = one_to_three()

Работает на моей установке Python.Если я проигнорирую избыточность, столь распространенную в примерах, представленную в этом коде, я увижу, что понимание генератора легко сопоставляется с генератором, созданным сопрограммой производителя.Будучи доктором Прагматиком, я пытался сопоставить ту же концепцию с диктатами, учитывая, что их понимание уже существует, и я думал, что эти два понятия будут эквивалентны:

one_to_three_doubles = {num : num * 2 for num in range(1, 4)}

...

def one_to_three_doubles():
    for num in range(1, 4):
        yield num : num * 2

one_to_three_doubles_gen = one_to_three_doubles()

Первый работает, а второй нет.Он отмечает синтаксическую ошибку в двоеточии в 3-й строке.

Теперь, либо я слегка подскакиваю по синтаксису, либо у меня возникло серьезное недопонимание того, как работают сопрограммы производителя.Я подозреваю, что он не работает по той же причине, по которой вы не можете заставить сопрограмму возвращать список, а не генератор, но я не знаю точно.

Так что, да, исправление этой ошибки - в основном то, что япрошу;заранее спасибо.Я предпочел бы ответ, который говорит мне ответ, а не дает мне совершенно новый способ достижения результата, но, очевидно, если это единственный способ ...

1 Ответ

20 голосов
/ 16 июля 2011

Dict-понимания работают как списки / наборы-определения и выражения генератора - X-понимание с "телом" expr for vars in iterable в значительной степени эквивалентно X(expr for vars in iterable) - и вы уже знаете, как превратить выражение генератора в генератор,Но обратите внимание на «довольно много», так как буквальный перевод не работает (как вы заметили) и не нужен вообще (не делает реализацию намного проще и на самом деле довольно хакерской).

У понимания Dict просто есть немного синтаксического сахара, чтобы больше походить на буквальные литералы (двоеточие).Семантически это не нужно - в этом нет ничего особенного.Остановитесь и задумайтесь на секунду: понимание dict должно производить два значения на каждой итерации, ключ и значение.Это именно то, что означает двоеточие - (key, value) пар (помните, что dict принимает итерацию из (key, value) пар).Вы не можете использовать этот синтаксический сахар вне понимания слов, но вы можете просто использовать кортежи для пар.Следовательно, эквивалентный генератор будет:

def one_to_three_doubles():
    for num in range(1, 4):
        yield num, num * 2
...