重复列表中的有序对

时间:2018-05-03 13:34:05

标签: python list-comprehension

我有一个列表可能有也可能没有重复元素,我希望创建有序对,使得在元素x中重复x,x是一个有效对,所有x,y当x

到目前为止,我已经找到了一种非常非恐怖的方法

def foo(a):
    n = list()
    for x in range(len(a)):
        for y in range(x+1,len(a)):
            if a[x] < a[y]:
                n.append([a[x],a[y]])
            else:
                n.append([a[y],a[x]])
    o = list()
    for p in n:
        if not (p in o):
            o.append(p)
    return o

print(foo([1,3,5,-1]))
# [[1, 3], [1, 5], [-1, 1], [3, 5], [-1, 3], [-1, 5]]

print(foo([1,1,5,5]))
# [[1, 1], [1, 5], [5, 5]]

print(foo([1,1,1,1]))
# [[1, 1]]

我知道我可以使用列表理解但我尝试的解决方案是在重复存在时跳过x,x类型或者幻像x,x不应该存在

a = [1,3,5,-1]
o = [[x,y] for x in a for y in a if x<=y]
print(o)
[[1, 1], [1, 3], [1, 5], [3, 3], [3, 5], [5, 5], [-1, 1], [-1, 3], [-1, 5], [-1, -1]]

什么是适合可读性的pythonic解决方案。

此外,如果pythonic解决方案不是最有效的,那么最有效的解决方案时间(内存不是约束)

3 个答案:

答案 0 :(得分:1)

如果您对使用itertools感到满意,可以使用itertools.combinations

from itertools import combinations

a = [1, 3, 5, -1]
o = sorted(set(combinations(sorted(a), 2)))

>>> [(-1, 1), (-1, 3), (-1, 5), (1, 3), (1, 5), (3, 5)]

a = [1, 1, 5, 5]
o = sorted(set(combinations(sorted(a), 2)))

>>> [(1, 1), (1, 5), (5, 5)]

sorted的内部调用确保每一对都会被订购,我理解这是您的意图。对sorted的外部调用可确保对对象进行排序。如果没有必要,您可以使用sorted替换此list

答案 1 :(得分:0)

您是否尝试过使用itertools.combinations()

像这样的东西

Author id 1 author 980190963 book 980190963
Author id 2 author 980190964 book 

答案 2 :(得分:0)

如果您itertools感到满意,您可以使用列表理解。

>>> xs = [1,3,5,-1]

如果您将xs与其自身的所有子列表一起压缩,从索引1,2,...,len(xs)-1开始,您将获得所有组合:

>>> [list(zip(xs,xs[n:])) for n in range(1,len(xs))]
[[(1, 3), (3, 5), (5, -1)], [(1, 5), (3, -1)], [(1, -1)]]

(请注意,我将zip包裹在list中以获得更好的输出。) 现在,你必须弄平元组列表。这只是对zip所产生的每个元组列表的每个元组的列表理解:

>>> [t for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys]
[(1, 3), (3, 5), (5, -1), (1, 5), (3, -1), (1, -1)]

您想要排序的元组:这是tuple(sorted(t))因为sorted会返回一个列表。将所有内容放在set中以删除重复项。

>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(-1, 1), (1, 3), (-1, 3), (1, 5), (-1, 5), (3, 5)}

(你也可以像蚕一样,在输出元组之前对列表进行排序。)其他测试用例:

>>> xs = [1,1,1,1]
>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(1, 1)}
>>> xs = [1,1,5,5]
>>> set(tuple(sorted(t)) for ys in [zip(xs,xs[n:]) for n in range(1,len(xs))] for t in ys)
{(1, 5), (5, 5), (1, 1)}

建议:您应该使用itertools ...

相关问题