Python: вложенный для циклов или «следующего» оператора - PullRequest
6 голосов
/ 06 сентября 2010

Я начинающий хобби, и я пишу петли, когда пишу python, вот так:

dict = {
    key1: {subkey/value1: value2} 
    ... 
    keyn: {subkeyn/valuen: valuen+1}
    }

for key in dict:
    for subkey/value in key:
       do it to it

Мне известно о "следующем" ключевом слове, которое будет достигать той же цели в одной строке (я задал вопрос о том, как его использовать, но не совсем понял).

Так что для меня вложенный цикл гораздо более читабелен. Почему же тогда люди используют «следующий»? Я где-то читал, что Python - это динамически типизируемый и интерпретируемый язык, и, поскольку + одновременно объединяет строки и числа сумм, он должен проверять типы переменных для каждой итерации цикла, чтобы узнать, что это за операторы и т. Д. Использование «следующий» предотвращает это каким-то образом ускоряет выполнение или это просто вопрос стиля / предпочтений?

1 Ответ

22 голосов
/ 06 сентября 2010

next очень важно продвигать итератор , когда необходимо , без этого улучшения, контролирующего явный цикл for.Например, если вы хотите «первый элемент в S, который больше 100», next(x for x in S if x > 100) даст его вам, ни суеты, ни суеты, ни ненужной работы (так как все заканчивается, как только найдется подходящий x) - и вы получите исключение (StopIteration), если неожиданно нет x, соответствующее условию.Если ожидается отсутствие совпадения, и вы хотите None в этом случае, next((x for x in S if x > 100), None) доставит это.Для этой конкретной цели вам может быть понятнее, если бы next был фактически назван first, но это предало бы его гораздо более общее использование.

Рассмотрим, например, задачу объединения нескольких последовательностей (например, объединение или пересечение отсортированных последовательностей - скажем, отсортированных файлов, где элементы являются строками).Опять же, next - это именно то, что доктор прописал, потому что ни одна из последовательностей не может доминировать над другими, контролируя «основную for петлю».Таким образом, предполагая, что для простоты дубликаты не могут существовать (условие, которое не сложно ослабить при необходимости), вы сохраняете пары (currentitem, itsfile) в списке, контролируемом heapq, и объединение становится легким ... но только благодаря магиииз next для продвижения правильного файла после использования его элемента, и только для этого файла.

import heapq

def merge(*theopentextfiles):
    theheap = []
    for afile in theopentextfiles:
        theitem = next(afile, '')
        if theitem: theheap.append((theitem, afile))
    heapq.heapify(theheap)
    while theheap:
        theitem, afile = heapq.heappop(theheap)
        yielf theitem
        theitem = next(afile, '')
        if theitem: heapq.heappush(theheap, (theitem, afile))

Просто попробуйте сделать что-нибудь в этом элегантном местебез next ...! -)

Можно продолжать в течение длительного времени, но оба варианта использования "продвигают итератор на одно место (не позволяя ему контролировать весь цикл for)"и "получить только первый элемент от итератора" для наиболее важных применений next.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...