作为学习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。
答案 0 :(得分:2)
你应该在这里使用生成器功能:
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)]
答案 1 :(得分: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))
或者,您也可以使用generator expression(此处:all_pairs
),这类似于列表推导,但是延迟评估。他们非常很有帮助,特别是在迭代组合时,products等。
答案 2 :(得分:0)
使用product
和ifilter
以及来自itertools的unique_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)