Подача неизвестной длины списка в качестве входных данных в функцию

#python

Вопрос:

 from itertools import product
vec=['A1','A2','A3']
vec2=['B1','B2',]
vec3=['C1','C2','C3']

result = list(product(vec, vec2, vec3,repeat=1))
result 
[('A1', 'B1', 'C1'),
 ('A1', 'B1', 'C2'),
 ('A1', 'B1', 'C3'),
 ('A1', 'B2', 'C1'),
 ('A1', 'B2', 'C2'),
 ('A1', 'B2', 'C3'),
 ('A2', 'B1', 'C1'),
 ('A2', 'B1', 'C2'),
 ('A2', 'B1', 'C3'),
 ('A2', 'B2', 'C1'),
 ('A2', 'B2', 'C2'),
 ('A2', 'B2', 'C3'),
 ('A3', 'B1', 'C1'),
 ('A3', 'B1', 'C2'),
 ('A3', 'B1', 'C3'),
 ('A3', 'B2', 'C1'),
 ('A3', 'B2', 'C2'),
 ('A3', 'B2', 'C3')]
 

vec,vec2,vec3 создаются из цикла vec4, который иногда может иметь некоторую длину. Мой вопрос в том, как мне подключить vec4 list(product(vec, vec2, vec3,repeat=1)) . Я не могу ввести его сам в цикл, я product тоже как-то хочу выбрать vec4. Как мне этого добиться?
vec4=['D1','D2','D3','D4']

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

1. можете ли вы предоставить vec4 ? Вы можете поместить все списки в один список (скажем lists ), а затем сделать itertools.product(*lists,repeat=1)

2. @Sujay отредактировал, пожалуйста, проверьте. Если мы поместим его в один список, декартово произведение будет другим. Не могли бы вы, пожалуйста, зациклить его и сказать мне, как это сделать?

Ответ №1:

Если вы используете все списки vec в одном списке списков, вы можете распаковать этот список при передаче его в функцию продукта:

 list_vecs = [vec, vec2, vec3, vec4]

list(product(*list_vecs, repeat=1))
 

Что касается * (обозначение звездочкой), смотрите документы python здесь:

Например, встроенная функция range() ожидает отдельные аргументы запуска и остановки. Если они недоступны отдельно, запишите вызов функции с помощью оператора* -, чтобы распаковать аргументы из списка или кортежа:

 >>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]
 

В случае vec4 , если это будет определено только позже, просто добавьте его в list_vecs : list_vecs.append(vec4)

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

1. Это действительно сработало, но я хочу знать, какая здесь польза от звездочки.

2. * предназначен для распаковки списка @Damandeep

3. @Sujay Спасибо, если вы можете найти решение каким-либо другим способом. Это будет для меня уроком.

4. @mcsoini Не могли бы вы, пожалуйста, ознакомиться с моими двумя недавними вопросами.

Ответ №2:

Это решение почти такое же, как у @mcsoini, но немного больше объяснений: Здесь,

 vec=[['A1','A2','A3'],
['B1','B2'],
['C1','C2','C3'],vec4]
 

vec это список списков. Первые 3 списка таковы vec1,2,3 . vec4 может быть добавлен позже. Кроме того, вы можете добавить дополнительные списки для vec использования vec.append(<list>)

Теперь, вместо того , чтобы делать vec[0],vec[1]... , мы просто будем использовать then * для распаковки списка. Это позволит передать все списки в itertools.product() .

 list(product(*vec,repeat=1))

 

Кроме того, это заботится о большей части списков, потому что vec[0]... выполнение не только утомительно, но и приводит к ошибкам, если индекс выходит за пределы диапазона, или будут учитываться только те списки, которые индексируются.

 vec=[['A1','A2','A3'],
['B1','B2'],
['C1','C2','C3'],vec4]

result = list(product(*vec,repeat=1))