从python

时间:2017-05-10 14:21:38

标签: python algorithm duplicates tuples uniqueidentifier

我正在编写一个找到重复文件的程序,现在我有一个元组列表

mylist = [(file1, size1, hash1),
          (file2, size2, hash2),
          ...
          (fileN, sizeN, hashN)]

我想删除具有唯一哈希的条目,只留下重复项。我正在使用

def dropunique(mylist):
templist = []
while mylist:
    mycandidate = mylist.pop()
    templist.append([mycandidate])
    for myfile in mylist:
        if myfile[-1] == mycandidate[-1]:
            templist[-1].append(myfile)
            mylist.remove(myfile)
for myfile in templist:
    if len(myfile) != 1:
        mylist.append(myfile)
templist = [item for sublist in mylist for item in sublist]
return templist

我弹出一个条目,看看是否有另一个具有相同散列和组的条目然后在具有相同散列的列表列表中。然后我使用len>的子列表创建另一个列表1并将生成的列表列表放到一个简单的列表中。 我的问题是,当我在mylist中使用' for myfile时从列表中删除一个条目:'在某些列表中,它会跳转相同的条目然后生活在后面。

4 个答案:

答案 0 :(得分:3)

将列表复制到以哈希为键的字典中,并在第二遍中删除具有单个计数的列表 - 您甚至可以使用collections.Counter来备用一行或两行代码:

from collections import Counter

counter = Counter(t[2] for t in list_)

result = [value for value in list_ if counter[value[2]] > 1]

(非相关提示:避免将变量命名为“list”或“dict” - 这将覆盖那些Python默认内置函数)

答案 1 :(得分:1)

我会使用defaultdict()按元组值对元组进行分组:

from collections import defaultdict

# Group the tuples by their hashvalues
d = defaultdict(list)
for tup in data:
    filename, size, hashvalue = tup
    d[hash].append(tup)

# Display groups of tuples that have more than one tuple
for hashvalue, tuples in d.items():
    if len(tuples) > 1:
        print('Tuples with %r in common' % hashvalue)
        for tup in tuples:
            print(tup)
        print()

答案 2 :(得分:1)

使用groupby的解决方案

from itertools import groupby

my_list = [(1, 2, 3),
           (1, 2, 3),
           (4, 5, 6)]


vals = []

for hash_val, items in groupby(sorted(my_list), hash):
    results = tuple(items)
    if len(results) > 1:
        vals.append(results[0])

答案 3 :(得分:0)

您可以像这样使用双filter

filter(lambda el: len(filter(lambda item: item[2] == el[2], my_list)) > 1, my_list)

<强>结果:

>>> my_list = [('file1', 'size1', 'hash1'), ('file2', 'size2', 'hash2'), ('file3', 'size3', 'hash3'), ('file4', 'size4', 'hash2')]
>>>
>>> filter(lambda el: len(filter(lambda item: item[2] == el[2], my_list)) > 1, my_list)
[('file2', 'size2', 'hash2'), ('file4', 'size4', 'hash2')]

请注意,在Python 3中,filter返回一个迭代器,因此您需要将其转换为如下列表:list(filter(...))