Я создаю функцию, которая принимает переменное количество списков в качестве входных данных (то есть arbitrary argument list). Мне нужно сравнить каждый элемент из каждого списка с каждым элементом всех других списков, но я не мог найти никакого способа приблизиться к этому.Создание комбинаций элементов из нескольких списков
ответ
Модуль itertools предоставляет множество полезных инструментов только для таких задач. Вы можете адаптировать следующий пример к своей задаче, интегрируя его в свою конкретную логику сравнения.
Заметим, что следующее предполагает коммутативную функцию. То есть около половины кортежей опущены по соображениям симметрии.
Пример:
import itertools
def generate_pairs(*args):
# assuming function is commutative
for i, l in enumerate(args, 1):
for x, y in itertools.product(l, itertools.chain(*args[i:])):
yield (x, y)
# you can use lists instead of strings as well
for x, y in generate_pairs("ab", "cd", "ef"):
print (x, y)
# e.g., apply your comparison logic
print any(x == y for x, y in generate_pairs("ab", "cd", "ef"))
print all(x != y for x, y in generate_pairs("ab", "cd", "ef"))
Выход:
$ python test.py
('a', 'c')
('a', 'd')
('a', 'e')
('a', 'f')
('b', 'c')
('b', 'd')
('b', 'e')
('b', 'f')
('c', 'e')
('c', 'f')
('d', 'e')
('d', 'f')
False
True
если вы хотите аргументы как словарь
def kw(**kwargs):
for key, value in kwargs.items():
print key, value
, если вы хотите, чтобы все аргументы как список:
def arg(*args):
for item in args:
print item
вы можете использовать как
def using_both(*args, **kwargs) :
kw(kwargs)
arg(args)
вызов это так:
using_both([1,2,3,4,5],a=32,b=55)
В зависимости от вашей цели вы можете использовать некоторые из утилит itertools
. Например, вы можете использовать itertools.product
на *args
:
from itertools import product
for comb in product(*args):
if len(set(comb)) < len(comb):
# there are equal values....
Но в настоящее время это не очень ясно из вашего вопроса, что вы хотите достичь. Если я не понял вас правильно, вы можете попытаться сформулировать вопрос более определенным образом.
Я думаю, @ ответ LevLeitsky является лучшим способом, чтобы сделать петлю над деталями из вашего переменного числа списков. Однако, если цель состоит в том, чтобы просто найти общие элементы между парами элементов из списков, я бы сделал это несколько иначе.
Вот такой подход, который находит общие элементы между каждой парой списков:
import itertools
def func(*args):
sets = [set(l) for l in args]
for a, b in itertools.combinations(sets, 2):
common = a & b # set intersection
# do stuff with the set of common elements...
Я не уверен, что вам нужно сделать с общими элементами, поэтому я оставлю его там.