Каков Pythonic способ получения списка списков и «распространения» элементов из другого списка в подсписки?

#python #list #append

#python #Список #добавить

Вопрос:

Я пытаюсь немного выучить Python чуть меньше двух недель. Итак, извините, если я просто полностью дезинформирован.

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

Допустим, у меня есть list1 = [[x, y], [a, b]] и list2 = [0, 1] .

Я хочу list3 = [[x, y, 0], [x, y, 1], [a, b, 0], [a, b, 1]]

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

[[x, y, 0], [a, b, 1]]

[[x, y, 0, 1], [a, b, 0, 1]]

[[x, y, 0, 1], [a, b]]

[[[x, y], 0], [[x, y], 1], [[a, b], 0], [[a, b], 1]]

То, что я рассматривал, заключалось бы в том, чтобы сделать что-то вроде следующего:

  1. Создайте столько итераций подсписков в списке1, сколько элементов в списке2 [[x, y], [a, b]] -> [[x, y], [x, y], [a, b], [a, b]]
  2. Сгладьте list1 так, чтобы это были уже не подсписки, а повторяющиеся элементы [[x, y], [x, y], [a, b], [a, b]] -> [x, y, x, y, a, b, a, b]
  3. Пройдите по элементам list1 и вставьте элементы list2 вдоль сжатого списка [x, y, x, y, a, b, a, b] -> [x, y, 0, x, y, 1, a, b, 0, a, b, 1]
  4. Сгруппируйте элементы в соответствующий размер: [x, y, 0, x, y, 1, a, b, 0, a, b, 1] -> [[x, y, 0], [x, y, 1], [a, b, 0], [a, b, 1]]

Если это то, что я должен сделать, то это то, что я должен сделать, и я ищу способ сделать это таким образом, но я чувствую, что должен быть какой-то более питонический способ выполнения этой операции (опять же, что я знаю?) и, если да, я изо всех сил пытаюсь выяснить, что бы это могло быть.

Ответ №1:

По сути, это просто перекрестный продукт двух списков.

 >>> import itertools
>>> list(itertools.product(list1, list2))
[(['x', 'y'], 0), (['x', 'y'], 1), (['a', 'b'], 0), (['a', 'b'], 1)]
  

Все, что осталось сделать, это выровнять каждый кортеж.

 >>> [x   [y] for x,y in itertools.product(list1, list2)]
[['x', 'y', 0], ['x', 'y', 1], ['a', 'b', 0], ['a', 'b', 1]]
  

Комментарии:

1. Спасибо! Это именно то, что я искал. В itertools я только просмотрел и попробовал cycle, но там мне не повезло, и я раньше не видел такой конкретной конструкции сглаживания кортежей внутри списка.

Ответ №2:

Я могу ошибаться, но я не думаю, что есть отличное решение itertools

 def permutations(a,b):
    for sublist in a:
        for value in b:
            yield sublist   [value]

list1 = [[x, y], [a, b]] 
list2 = [0, 1]
print(list(permutations(list1, list2)))
  

Ответ №3:

Используя только понимание списка:

 list3 = [list[:]   [elem] for list in list1 for elem in list2]
  

Комментарии:

1. Приведенный вами здесь код не обеспечивает поведение, которое я ищу. Используя мой пример, это сгенерировало: [ [ [x, y], [a, b], 0], [ [x, y], [a, b], 1], [ [x, y], [a, b], 0], [ [x, y], [a, b], 1]]

2. Этот код (скопированный и вставленный) дает мне именно то, что вы ищете. Возможно, ошибка ввода?

3. Я также скопировал и вставил. Если я отредактировал его так, чтобы он был [list [elem] для списка в list1 для элемента в list2], то это сработало, но list[:] дал мне ответ, который я прокомментировал выше. Приятно знать, что для этого есть простое понимание списка! РЕДАКТИРОВАТЬ: О, неважно! Вы были правы; когда я скопировал и вставил его, чтобы поиграть с ним, я не менял список ключевых слов на что-то другое. Меняем его на list_[:] [elem] для list_ … сделал свое дело.

4. Рад, что все отсортировано. Хотя ключевое слово ‘list’ переопределено (overridden?) в определении цикла for so не должно иметь значения. Кроме того, использование [:] или нет ничего бы не изменило, поскольку оба возвращают копию списка, а выражение приводит к объединению двух списков. Я подозреваю, что у вас был заполненный ‘list3’ перед запуском понимания. В противном случае я буду немного озадачен!