从 python 中的元组列表中删除唯一元组
Remove unique tuples from a list of tuples in python
我正在编写一个查找重复文件的程序,现在我有一个元组列表
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 的子列表制作另一个列表,并将结果列表列表平整为一个简单列表。
我的问题是,当我在某些列表上使用 'for myfile in mylist:' 时从列表中删除一个条目时,它会跳转相同的条目并在后面生活。
将您的列表复制到以散列为键的字典中,然后在第二遍中删除具有单个计数的列表 - 您甚至可以使用 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 默认的内置函数)
我会使用 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()
使用 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])
您可以像这样使用双 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
returns 是一个迭代器,因此您需要将其转换为这样的列表:list(filter(...))
我正在编写一个查找重复文件的程序,现在我有一个元组列表
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 的子列表制作另一个列表,并将结果列表列表平整为一个简单列表。 我的问题是,当我在某些列表上使用 'for myfile in mylist:' 时从列表中删除一个条目时,它会跳转相同的条目并在后面生活。
将您的列表复制到以散列为键的字典中,然后在第二遍中删除具有单个计数的列表 - 您甚至可以使用 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 默认的内置函数)
我会使用 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()
使用 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])
您可以像这样使用双 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
returns 是一个迭代器,因此您需要将其转换为这样的列表:list(filter(...))