简体   繁体   English

生成多个列表中元素的组合

[英]Generate combinations of elements from multiple lists

I'm making a function that takes a variable number of lists as input (ie, an arbitrary argument list ). 我正在创建一个函数,它将可变数量的列表作为输入(即任意参数列表 )。 I need to compare each element from each list to each element of all other lists, but I couldn't find any way to approach this. 我需要将每个列表中的每个元素与所有其他列表中的每个元素进行比较,但我找不到任何方法来解决这个问题。

Depending on your goal, you can make use of some of the itertools utilities. 根据您的目标,您可以使用一些itertools实用程序。 For example, you can use itertools.product on *args : 例如,您可以在*args上使用itertools.product

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

But currently it's not very clear from your question what you want to achieve. 但是目前从你的问题中不清楚你想要实现什么。 If I didn't understand you correctly, you can try to state the question in a more specific way. 如果我没有正确理解您,您可以尝试以更具体的方式陈述问题。

I think @LevLeitsky's answer is the best way to do a loop over the items from your variable number of lists. 我认为@LevLeitsky的答案是对可变数量的列表中的项进行循环的最佳方法。 However, if purpose the loop is just to find common elements between pairs of items from the lists, I'd do it a bit differently. 但是,如果循环只是为了找到列表中的项目对之间的公共元素,我会做的有点不同。

Here's an approach that finds the common elements between each pair of lists: 这是一种在每对列表之间找到共同元素的方法:

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...

I'm not sure what you need to do with the common elements, so I'll leave it there. 我不确定你需要对共同的元素做什么,所以我会留在那里。

if you want the arguments as dictionary 如果你想把参数作为字典

def kw(**kwargs):
    for key, value in kwargs.items():
        print key, value

if you want all the arguments as list: 如果你想要所有的参数作为列表:

 def arg(*args):
        for item in args:
            print item

you can use both 你可以两者兼得

def using_both(*args, **kwargs) :
     kw(kwargs)
     arg(args)

call it like that: 这样称呼它:

using_both([1,2,3,4,5],a=32,b=55)

The itertools module provides a lot of useful tools just for such tasks. itertools模块为这些任务提供了许多有用的工具。 You can adapt the following example to your task by integrating it into your specific comparison logic. 您可以通过将以下示例集成到您的特定比较逻辑中来使其适应您的任务。

Note that the following assumes a commutative function. 请注意,以下假定具有可交换功能。 That is, about half of the tuples are omitted for reasons of symmetry. 也就是说,出于对称的原因,省略了大约一半的元组。

Example: 例:

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

Output: 输出:

$ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM