2

作为学习 Python 的一部分,我为自己设定了一些挑战,以了解各种做事方式。我目前的挑战是使用列表理解创建一个对列表。第一部分是列出一个配对列表,其中 (x,y) 不能相同(x 不等于 y)并且顺序很重要((x,y) 不等于 (y,x))。

return [(x,y) for x in listOfItems for y in listOfItems if not x==y]

使用我现有的代码是否可以修改它,所以如果 (x,y) 已经存在于列表中,因为 (y,x) 从结果中排除它?我知道我可以逐字比较项目,但我想看看你可以通过列表理解来控制多少。

我正在使用 Python 2.7。

4

3 回答 3

3

您应该在这里使用生成器函数:

def func(listOfItems):
    seen = set()  #use set to keep track of already seen items, sets provide O(1) lookup  
    for x in listOfItems:
        for y in listOfItems:
            if x!=y and (y,x) not in seen:
                seen.add((x,y)) 
                yield x,y

>>> lis = [1,2,3,1,2]
>>> list(func(lis))
[(1, 2), (1, 3), (1, 2), (2, 3), (1, 2), (1, 3), (1, 2), (2, 3)]
于 2013-05-19T10:05:12.590 回答
1
def func(seq):
    seen_pairs = set()
    all_pairs = ((x,y) for x in seq for y in seq if x != y)
    for x, y in all_pairs:
        if ((x,y) not in seen_pairs) and ((y,x) not in seen_pairs):
            yield (x,y)
        seen_pairs.add((x,y))

或者,您也可以使用生成器表达式(此处 all_pairs为:),它类似于列表推导式,但是是惰性求值的。它们非常有用,尤其是在迭代组合、产品等时。

于 2013-05-19T10:42:28.997 回答
0

使用productifilter以及来自itertoolsunique_everseen的配方

>>> x = [1, 2, 3, 1, 2]
>>> x = product(x, x)
>>> x = unique_everseen(x)
>>> x = ifilter(lambda z: z[0] != z[1], x)
>>> for y in x:
...     print y
... 
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
于 2013-05-19T11:32:06.250 回答