检查列表中是否有重复的列表

12

给定一个列表的列表,我想确保没有两个列表具有相同的值和顺序。例如对于 my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]],它应该返回重复列表的存在,即[1, 2, 4, 6, 10]

我使用了while,但它并不按照我的意愿工作。请问有人知道如何修复这段代码吗?

routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
r = len(routes) - 1
i = 0
while r != 0:
    if cmp(routes[i], routes[i + 1]) == 0:
        print "Yes, they are duplicate lists!"
    r -= 1
    i += 1
7个回答

13

你可以在列表推导式中计算出现次数,将它们转换为tuple以便哈希和应用唯一性:

routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
dups = {tuple(x) for x in routes if routes.count(x)>1}

print(dups)

结果:

{(1, 2, 4, 6, 10)}

很简单,但是由于重复调用 count 导致底层有很多循环。还有另一种方法,涉及哈希但复杂度较低,可以使用 collections.Counter

from collections import Counter

routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]

c = Counter(map(tuple,routes))
dups = [k for k,v in c.items() if v>1]

print(dups)

结果:

[(1, 2, 4, 6, 10)]

只需对转换为元组的子列表进行计数 - 修复哈希问题 - 并使用列表推导式生成重复项列表,仅保留出现多次的项。

现在,如果您只想检测是否存在一些重复的列表(而不打印它们),您可以:

  • 将列表中的列表转换为元组列表,以便您可以在集合中进行哈希
  • 比较列表的长度与集合的长度:

如果有一些重复项,则长度会不同:

routes_tuple = [tuple(x) for x in routes]    
print(len(routes_tuple)!=len(set(routes_tuple)))

在Python 3中能够使用map函数已经足够罕见,所以必须提及:

print(len(set(map(tuple,routes))) != len(routes))

3
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
dups = set()

for route in routes:
    if tuple(route) in dups:
        print('%s is a duplicate route' % route)
    else:
        dups.add(tuple(route))

2

不确定您是否需要外部库,但我有一个专门为此目的设计的库函数:iteration_utilities.duplicates

>>> from iteration_utilities import duplicates

>>> my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]]

>>> list(duplicates(my_list, key=tuple))
[[1, 2, 4, 6, 10]]

请注意,即使没有key=tuple,它也可以正常工作,但其行为将是O(n*n)而不是O(n)
>>> list(duplicates(my_list))
[[1, 2, 4, 6, 10]]

它还可以保持出现顺序(无论是否有“key”)如果这很重要:
>>> list(duplicates([[1], [2], [3], [1], [2], [3]]))
[[1], [2], [3]]

如果您只关心是否存在重复项,可以使用any而不是list

>>> any(duplicates([[1], [2], [3], [1], [2], [3]]))
True
>>> any(duplicates([[1], [2], [3]]))
False

0

你可以使用numpy库中的unique()函数来以简洁的方式解决它。正如在numpy文档中所写的那样,你可以按照以下步骤进行:

import numpy as np

unique_lists_in_list = np.unique(routes , axis=0)

您可以随后比较长度。如果它们具有相同的长度,则表示路由没有重复。
if len(unique_lists_in_list) == len(routes):
    print("All lists inside the routes list aren't duplicate")

0
使用“反向”切片(它是有序的)创建一个列表推导式,其中不包含重复项。
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]

routes_cleaned = [l for i, l in enumerate(routes) if l not in routes[:i]]

print(len(routes_cleaned) == len(route))
print(routes_cleaned)

输出

False
[[1, 2, 4, 6, 10], [1, 3, 8, 9, 10]]


0
for x in routes:

    print x, routes.count(x)

这将返回每个列表及其出现次数。或者,您可以仅显示出现次数>1的列表:

new_list = []

for x in routes:

    if routes.count(x)>1:

        if x not in new_list:

            new_list.append(x)

for x in new_list:

    print x, routes.count(x)

希望能有所帮助!


0
def duplicate(lst):
    cntrin=0
    cntrout=0
    for i in lst:
        cntrin=0
        for k in lst:
            if i==k:
                cntrin=cntrin+1
        if cntrin>1:
            cntrout=cntrout+1
    if cntrout>0:
        return True
    else:
        return False

愉快编程!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接