2010-01-30 3 views
5

У меня есть список L = [а, Ь, с], и я хочу, чтобы создать список кортежей:Список умножение

[(a,a), (a,b), (a,c), (b,a), (b,b), (b,c)...] 

Я пытался делать L * L, но это не сработало. Может кто-нибудь сказать мне, как получить это в python.

+0

Этот вид «продукта» также называется «декартовым произведением» или «прямым продуктом» (я не уверен, что здесь более уместен один термин или другой, но сам документ Python использует «декартово произведение»). – MatrixFrog

ответ

13

Модуль itertools содержит целый ряд полезных функций для такого рода вещи. Похоже, что вы можете искать product:

>>> import itertools 
>>> L = [1,2,3] 
>>> itertools.product(L,L) 
<itertools.product object at 0x83788> 
>>> list(_) 
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] 
7

Посмотрите на модуль itertools, который содержит элемент product.

L =[1,2,3] 

import itertools 
res = list(itertools.product(L,L)) 
print(res) 

Дает:

[(1,1),(1,2),(1,3),(2,1), .... and so on] 
22

Вы можете сделать это с помощью списка понимания:

[ (x,y) for x in L for y in L] 

редактировать

Вы также можете использовать itertools.product как и другие рекомендуется, но только если вы используете 2,6 и более. Понимание списка будет работать, все версии Python от 2.0. Если вы используете itertools.product, имейте в виду, что он возвращает генератор вместо списка, поэтому вам может понадобиться его преобразовать (в зависимости от того, что вы хотите с ним делать).

+0

Спасибо за разъяснение. – Schitti

0

х = [а, б, в] у = [] для элемента х: для item2 х: y.append ((пункт, элемент2))

Может быть, не питоновский путь но работает

0

Ok я пытался:

L2 = [(х, у) при й в L для й в L], и это есть L квадрат.

Это лучший питонический способ сделать это? Я ожидал бы, что L * L будет работать на python.

+0

Неверные ожидания - последовательность «последовательность» ** не определена ** (только 'sequence * int', что делает что-то ** очень ** другое! -). –

+0

Упс, написал это, прежде чем я увидел ответы. Пожалуйста, игнорируйте – Schitti

3

две основные альтернативы:

>>> L = ['a', 'b', 'c'] 
>>> import itertools 
>>> list(itertools.product(L, L)) 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> [(one, two) for one in L for two in L] 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> 

прежний необходим Python 2.6 или лучше - последние работы практически в любой версии Python вы можете быть привязаны к.

+0

Использование itertools кажется странным для меня, если вы просто собираетесь конвертировать непосредственно в список в любом случае.Понимание списка, вероятно, более эффективно, так же, как читаемо и, вероятно, более удобно в том, что есть хитрости, которые вы можете сделать непосредственно для выражения. Более абстракция может означать большую негибкость, и все дело в том, чтобы скрыть детали, которые вы * надеетесь * (но не можете быть уверены) вам больше не придется беспокоиться. – Steve314

0

Самый старомодный способ сделать это будет:

def perm(L): 
    result = [] 
    for i in L: 
     for j in L: 
      result.append((i,j)) 
    return result 

Это имеет время выполнения O (N^2) и, следовательно, довольно медленно, но вы могли бы рассмотреть его «винтаж» стиль код.

+0

Все подходы к этому имеют O (n^2) время выполнения в лучшем случае, поскольку все они должны генерировать кортежи O (n^2). Использование итератора, такого как itertools, позволяет отложить часть этой работы, но вы не можете полностью ее избежать. Возможно, ваш подход может быть O (n^3) - добавление к спискам вполне может быть O (n), а не O (1) из-за проблем с перераспределением памяти, хотя я точно не помню. Я * думаю * в списке Python используется изменяемый размер массива - * не * связанный список. Однако может быть какая-то оптимизация append. Понимание списка * возможно * предопределяет весь массив в начале. – Steve314

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