2011-03-31 4 views
15

я могу использовать if и for в списковых/выражений генератора в качествеИспользование в то время как в списке понимание или генератор выражений

list(i for i in range(100) if i*i < 30) 

Я знаю, что это не самый эффективный, но медведь со мной, как условие может быть гораздо больше сложный, и это всего лишь пример. Тем не менее, это все еще проходит через сотни итераций и только дает значение в первой 6. Есть ли способ сказать выражение генератора, где остановиться с чем-то вроде этого:

list(i for i in range(100) while i*i < 30) 

Однако while не понят в генераторе выражения. Итак, мой вопрос: как написать выражение генератора с условием остановки, чтобы он не продолжал вычисление, даже если он не дает новых значений.

+1

Только примечание: вы можете сгенерировать список напрямую, используя '[i для i в диапазоне (100)]' – Joril

+0

Любопытно, что был [PEP3142] (https://www.python.org/dev/peps/ pep-3142 /), открытый в то время, когда задавался этот вопрос. Приведенный пример использования почти такой. Гвидо обнародовал его в мае 2013 года –

ответ

9

Различные функции в itertools (takewhile() приходят на ум) могут помочь.

20

Поскольку синтаксис takewhile() и dropwhile() не ярким, вот реальные примеры вашего вопроса:

>>> [i for i in itertools.takewhile(lambda x: x*x<30, range(10))] 
[0, 1, 2, 3, 4, 5] 
>>> [i for i in itertools.dropwhile(lambda x: x*x<30, range(10))] 
[6, 7, 8, 9] 

Знайте, что автор itertools has questioned ли принизить эти функции.

+0

Что было бы рецептом в случае, если эти функции устарели? – highBandWidth

+0

Просто посмотрите на документы Python для [itertools.takewhile] (http://docs.python.org/library/itertools.html#itertools.takewhile) и [itertools.dropwhile] (http://docs.python.org /library/itertools.html#itertools.dropwhile). Каждый из них имеет прямой эквивалент Python. – dawg

+6

не просто 'list (itertools.takewhile (lambda x: x * x <30, range (10)))' проще, чем понимание здесь – wim

 Смежные вопросы

  • Нет связанных вопросов^_^