Как соединить строки из декартова произведения двух списков - PullRequest
0 голосов
/ 08 мая 2020

У меня есть два списка строк:

letters = ['abc', 'def', 'ghi']
numbers = ['123', '456']

Я хочу для l oop через них создать список строк, который не параллелен, поэтому zip() здесь не работает.

Желаемый результат:

result = ['abc123', 'def123', 'ghi123', 'abc456', 'def456', 'ghi456']

Порядок элементов в результате не имеет значения.

Есть идеи?

Ответы [ 4 ]

9 голосов
/ 08 мая 2020

Вы можете попробовать понимание списка с двумя вложенными для l oop над numbers, а затем letters:

print([l+n for n in numbers for l in letters])
# ['abc123', 'def123', 'ghi123', 'abc456', 'def456', 'ghi456']

Вы также можете использовать вложенный для l oop:

out = []
for n in numbers:
    for l in letters:
        out.append(l+n)
print(out)
# ['abc123', 'def123', 'ghi123', 'abc456', 'def456', 'ghi456']

Для получения дополнительных сведений о понимании списка см. do c или эту связанную topi c .

1 голос
/ 08 мая 2020

Возьмите произведение numbers и letters (а не letters и numbers), но затем соедините полученные кортежи в обратном порядке.

>>> from itertools import product
>>> [''.join([y, x]) for x, y in product(numbers, letters)]
['abc123', 'def123', 'ghi123', 'abc456', 'def456', 'ghi456']

Для 2-кортежей будет достаточно y + x вместо использования ''.join.

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

>>> list(product(numbers, letters))
[('123', 'abc'), ('123', 'def'), ('123', 'ghi'), ('456', 'abc'), ('456', 'def'), ('456', 'ghi')]
0 голосов
/ 08 мая 2020

Учитывая ваши списки префиксов letters и суффиксов numbers, которые необходимо объединить

letters = ['abc', 'def', 'ghi']
numbers = ['123', '456']

Basi c

Первое решение, которое приходит на ум (особенно если вы новичок в Python) использует вложенные циклы

result = []
for s in letters:
    for n in numbers:
        result.append(s+n)

, и поскольку, как вы сказали, порядок не имеет значения, также будет допустимым решением следующее:

result = []
for n in numbers:
    for s in letters:
        result.append(s+n)

наиболее важным недостатком обоих является то, что вам нужно определить переменную result раньше, чтобы это выглядело немного слабым.

Advanced

Если вы переключитесь на понимание списка вы можете удалить эту лишнюю строку

result = [s+n for n in numbers for s in letters]

Эксперт

Математически говоря, вы создаете декартово произведение из numbers и letters. Python предоставляет функцию именно для этой цели с помощью itertools.product (который, кстати, также устраняет двойные for s)

from itertools import product
result = [''.join(p) for p in product(letters, numbers)]

это может показаться излишним в вашем примере, но как только дело доходит до большего количества компонентов для построения результатов, это может быть большая разница, и все инструменты, представленные здесь, кроме itertools.product, будут иметь тенденцию взорваться.

Для иллюстрации я завершаю примером, который перебирает префиксы, инфиксы и постфиксы:

print([''.join(p) for p in product('ab', '+-', '12')])

, который дает следующий результат:

['a+1', 'a+2', 'a-1', 'a-2', 'b+1', 'b+2', 'b-1', 'b-2']
0 голосов
/ 08 мая 2020

Спасибо за ответы! Я упростил случай, поэтому все вышеперечисленные решения работают хорошо, однако в реальной проблеме, над которой я работаю, я хочу добавить больше строк кода между ними, которые будут повторяться по обоим спискам. Я завершил их вложением циклов for:

for letter in letters:
   for number in numbers:
      print(letter+number)
      # many many lines of more code

В любом случае, большое спасибо за вашу помощь!

...