В Python, есть ли краткий способ использовать понимание списка с несколькими итераторами? - PullRequest
7 голосов
/ 01 декабря 2008

По сути, я хотел бы построить понимание списка над «декартовым произведением» двух итераторов. Подумайте о следующем коде Haskell :

[(i,j) | i <- [1,2], j <- [1..4]]

, что дает

[(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4)]

Можно ли получить подобное поведение в Python в сжатой форме?

Ответы [ 4 ]

17 голосов
/ 01 декабря 2008

Вы спрашиваете об этом?

[ (i,j) for i in range(1,3) for j in range(1,5) ]
7 голосов
/ 01 декабря 2008

Декартово произведение находится в модуле itertools (в 2.6).

>>> import itertools
>>> list(itertools.product(range(1, 3), range(1, 5)))
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4)]
5 голосов
/ 01 декабря 2008

Забавный факт о вложенном понимании: он имитирует вложенные циклы «for», поэтому внутренние могут использовать значения из внешних. Это не полезно в случае декартовых произведений, но полезно знать. Например:

[ (i,j) for i in range(10) for j in range(i) ] 

генерирует все пары (i,j), где 0>=i>j>10.

2 голосов
/ 01 декабря 2008

Это похоже на то, что вы описываете:

[[a, b] для a в диапазоне (1,3) для b в диапазоне (1,5)]

ОБНОВЛЕНИЕ: Драт! Должны были перезагрузить страницу, чтобы увидеть ответ С. Лотта перед публикацией. Хммм ... что делать для небольшой добавленной стоимости? Возможно, короткое свидетельство о полезности интерактивного режима с Python.

Я пришел совсем недавно из Perl, поэтому с такими проблемами я нахожу очень полезным набирать "python" в командной строке и переходить в интерактивный режим и просто: нажимая стрелку вверх и корректируя мою предыдущую попытку, пока я не получу то, что хочу. Всякий раз, когда я запутываюсь в каком-то ключевом слове, помощь всегда под рукой. Просто введите: help ("some_keyword"), прочитайте краткую сводку, затем нажмите "Q", и я снова в сети, чтобы напрямую поговорить с интерпретатором Python.

Рекомендуется, если вы новичок и не используете его.

...