Python, вложенный в генератор V и Loop для многократной итерации по списку, предоставленному функцией - PullRequest
2 голосов
/ 29 октября 2011

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

На данный момент мой код выглядит примерно так:

generator = iter([])
while Condition:
    try:
        item = next(generator)
    except StopIteration:
        generator = iter(list_returining_method())
        item = next(generator)
    ...

Однако ранее я использовал вложенный цикл for.

while Condition:
    for item in list_returining_method():
        ...

Хотя моя предыдущая попытка выглядит в некоторых отношениях лучше, но мой нынешний метод имеет некоторые "преимущества":

  • Если для условия задано значение false, цикл завершается без необходимости break из цикла for.
    • расширение вышеуказанных причин, методы с доступом к Condition могут завершить цикл без , перебирая все остальные элементы в указанном списке или осуществляя специальную проверку в цикле for.
  • Первый подход позволяет пропустить элементы в цикле, если возникнет такая необходимость.
  • Существует также еще один уровень отступа. Это больше тщеславия, чем что-либо еще, но, учитывая, что реальный код был частью метода класса, уровень отступа уже был довольно высок.

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

Ответы [ 2 ]

2 голосов
/ 29 октября 2011

Я бы посоветовал вам использовать несколько итераторов

items = itertools.chain.from_iterable( iter(list_returning_method, None) )

for item in items:
    # do something with item
    print item

    if not Condition:
       break

iter(callable, sentinel) возвращает итератор, который выдает результат callable () до тех пор, пока не вернется sentinel.Итератор, который выравнивает исходный итератор, он выдаст значения в списках, созданных первым итератором.

Я думаю, что это дает вам большинство преимуществ вашего метода, но с более чистым стилем.

1 голос
/ 29 октября 2011

Здесь есть место для мнений, но краткость второго подхода делает его очевидной победой, насколько я понимаю.Особенно, если использование переменной item ограничено циклом, я бы выбирал синтаксис for / in каждый раз.Были некоторые проблемы, связанные с буферами и изменениями состояния внутри цикла, где я решил не использовать для / in. Но это небольшое меньшинство.

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