简体   繁体   English

pythonic生成对的方法

[英]The pythonic way to generate pairs

I want something like code below, but "pythonic" style or using standard library: 我想要下面的代码,但“pythonic”风格或使用标准库:

def combinations(a,b):
    for i in a:
        for j in b:
             yield(i,j)

These are not really "combinations" in the sense of combinatorics, these are rather elements from the cartesian product of a and b . 这些在组合学意义上并不是真正的“组合”,这些是来自ab的笛卡尔积的元素。 The function in the standard library to generate these pairs is itertools.product() : 标准库中用于生成这些对的函数是itertools.product()

for i, j in itertools.product(a, b):
    # whatever

As @Sven said, your code is attempting to get all ordered pairs of elements of the lists a and b . 正如@Sven所说,你的代码试图获得列表ab所有有序元素对。 In this case itertools.product(a,b) is what you want. 在这种情况下, itertools.product(a,b)就是你想要的。 If instead you actually want "combinations", which are all unordered pairs of distinct elements of the list a , then you want itertools.combinations(a,2) . 相反,如果你真的想要“组合”,它们都是列表a中不同元素的无序对,那么你需要itertools.combinations(a,2)

>>> for pair in itertools.combinations([1,2,3,4],2):
...    print pair
...
(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)

The itertools library has combinatorics functions. itertools库具有组合函数。 Like Sven stated, itertools.product would be the appropriate function in this case: 像Sven所说,在这种情况下, itertools.product将是适当的函数:

list(itertools.product('ab', 'cd'))
[('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd')]

A nested generator expression will work too: 嵌套的生成器表达式也可以使用:

product = ((i, j) for i in a for j in b)
for i, j in product:
    # ...
>>>a=[1,2,3]
>>>b=[4,5,6]
>>>zip(a,b)
[(1, 4), (2, 5), (3, 6)] 

Create set of pairs (even,odd) combination 创建一对(偶数,奇数)组合

>>> a = { (i,j) for i in range(0,10,2) for j in range(1,10,2)}  
>>> a
{(4, 7), (6, 9), (0, 7), (2, 1), (8, 9), (0, 3), (2, 5), (8, 5), (4, 9), (6, 7), (2, 9), (8, 1), (6, 3), (4, 1), (4, 5), (0, 5), (2, 3), (8, 7), (6, 5), (0, 1), (2, 7), (8, 3), (6, 1), (4, 3), (0, 9)}

def combinations(lista, listb):
    return { (i,j) for i in lista for j in listb }

>>> combinations([1,3,5,6],[11,21,133,134,443])
{(1, 21), (5, 133), (5, 11), (5, 134), (6, 11), (6, 134), (1, 443), (3, 11), (6, 21), (3, 21), (1, 133), (1, 134), (5, 21), (3, 134), (5, 443), (6, 443), (1, 11), (3, 443), (6, 133), (3, 133)}

A question we might ask is whether you want to generate all ordered pairs or all unordered pairs. 我们可能会问的一个问题是,您是要生成所有有序对还是所有无序对。 The nested generator expression provided in the answer by mhyfritz will give you all ordered pairs. mhyfritz在答案中提供的嵌套生成器表达式将为您提供所有有序对。

If you want all unordered pairs (that is, (1, 2) and (2, 1) counts as the same pair), then you need to filter out the duplicates. 如果您希望所有无序对(即(1,2)和(2,1)计为同一对),则需要过滤掉重复项。 An easy way to do this is to add a conditional to the end of the generator expression like so: 一个简单的方法是在生成器表达式的末尾添加一个条件,如下所示:

myList= [1, 2, 3, 4, 5]
unorderedPairGenerator = ((x, y) for x in myList for y in myList if y > x)
for pair in unorderedPairGenerator:
    print(pair)
#(1, 2)
#(1, 3)
#(1, 4)
#(1, 5)
#(2, 3)
#(2, 4)
#(2, 5)
#(3, 4)
#(3, 5)
#(4, 5)

As an aside, I was given a question similar to this in a software interview, where they wanted me to generate all pairs from a list of numbers (without using a library function). 顺便说一句,我在软件访谈中遇到了类似的问题,他们希望我从数字列表中生成所有对(不使用库函数)。 At first I generated all the ordered pairs, and then they asked me to only generate the unordered pairs. 起初我生成了所有有序对,然后他们让我只生成无序对。 Being able to work with permutations and combinations is a pretty essential coding skill! 能够使用排列和组合是一项非常重要的编码技巧!

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

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