2013-04-21 6 views
0

Я создаю функцию, которая принимает переменное количество списков в качестве входных данных (то есть arbitrary argument list). Мне нужно сравнить каждый элемент из каждого списка с каждым элементом всех других списков, но я не мог найти никакого способа приблизиться к этому.Создание комбинаций элементов из нескольких списков

ответ

0

Модуль 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 
0

если вы хотите аргументы как словарь

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) 
1

В зависимости от вашей цели вы можете использовать некоторые из утилит itertools. Например, вы можете использовать itertools.product на *args:

from itertools import product 
for comb in product(*args): 
    if len(set(comb)) < len(comb): 
     # there are equal values.... 

Но в настоящее время это не очень ясно из вашего вопроса, что вы хотите достичь. Если я не понял вас правильно, вы можете попытаться сформулировать вопрос более определенным образом.

1

Я думаю, @ ответ 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... 

Я не уверен, что вам нужно сделать с общими элементами, поэтому я оставлю его там.