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

时间:2021-07-10 21:26:27

I'm making a function that takes a variable number of lists as input (i.e., 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.

我正在创建一个函数,它将可变数量的列表作为输入(即任意参数列表)。我需要将每个列表中的每个元素与所有其他列表中的每个元素进行比较,但我找不到任何方法来解决这个问题。

4 个解决方案

#1


0  

The itertools module provides a lot of useful tools just for such tasks. You can adapt the following example to your task by integrating it into your specific comparison logic.

itertools模块为这些任务提供了许多有用的工具。您可以通过将以下示例集成到您的特定比较逻辑中来使其适应您的任务。

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

#2


1  

Depending on your goal, you can make use of some of the itertools utilities. For example, you can use itertools.product on *args:

根据您的目标,您可以使用一些itertools实用程序。例如,您可以在* 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.

但目前从你的问题中不清楚你想要实现什么。如果我没有正确理解您,您可以尝试以更具体的方式陈述问题。

#3


1  

I think @LevLeitsky's answer is the best way to do a loop over the items from your variable number of lists. 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.

我认为@LevLeitsky的答案是对可变数量列表中的项进行循环的最佳方法。但是,如果循环只是为了找到列表中的项目对之间的公共元素,我会做的有点不同。

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.

我不确定你需要对共同的元素做什么,所以我会留在那里。

#4


0  

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)

#1


0  

The itertools module provides a lot of useful tools just for such tasks. You can adapt the following example to your task by integrating it into your specific comparison logic.

itertools模块为这些任务提供了许多有用的工具。您可以通过将以下示例集成到您的特定比较逻辑中来使其适应您的任务。

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

#2


1  

Depending on your goal, you can make use of some of the itertools utilities. For example, you can use itertools.product on *args:

根据您的目标,您可以使用一些itertools实用程序。例如,您可以在* 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.

但目前从你的问题中不清楚你想要实现什么。如果我没有正确理解您,您可以尝试以更具体的方式陈述问题。

#3


1  

I think @LevLeitsky's answer is the best way to do a loop over the items from your variable number of lists. 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.

我认为@LevLeitsky的答案是对可变数量列表中的项进行循环的最佳方法。但是,如果循环只是为了找到列表中的项目对之间的公共元素,我会做的有点不同。

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.

我不确定你需要对共同的元素做什么,所以我会留在那里。

#4


0  

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)