我想删除列表中的一定数量的重复项而不删除所有列表。例如,我有一个列表[1,2,3,4,4,4,4,4]
,我想要删除4个中的3个,以便我留下[1,2,3,4,4]
。一种天真的方式可能是
def remove_n_duplicates(remove_from, what, how_many):
for j in range(how_many):
remove_from.remove(what)
有没有办法在列表中一次删除三个4,但保留其他两个。
答案 0 :(得分:6)
如果您只想从列表中删除某些事件的n
次,那么使用生成器很容易:
def remove_n_dupes(remove_from, what, how_many):
count = 0
for item in remove_from:
if item == what and count < how_many:
count += 1
else:
yield item
用法如下:
lst = [1,2,3,4,4,4,4,4]
print list(remove_n_dupes(lst, 4, 3)) # [1, 2, 3, 4, 4]
如果我们使用一些额外的辅助存储,保持指定数量的任何项目的副本同样容易:
from collections import Counter
def keep_n_dupes(remove_from, how_many):
counts = Counter()
for item in remove_from:
counts[item] += 1
if counts[item] <= how_many:
yield item
用法类似:
lst = [1,1,1,1,2,3,4,4,4,4,4]
print list(keep_n_dupes(lst, 2)) # [1, 1, 2, 3, 4, 4]
此处输入是您要保留的列表和最大项目数。需要注意的是,物品需要可以清洗......
答案 1 :(得分:0)
你可以使用Python的设置功能和&amp;运算符以创建列表列表,然后展平列表。结果列表将是[1,2,3,4,4]。
x = [1,2,3,4,4,4,4,4]
x2 = [val for sublist in [[item]*max(1, x.count(item)-3) for item in set(x) & set(x)] for val in sublist]
作为一项功能,您将拥有以下内容。
def remove_n_duplicates(remove_from, what, how_many):
return [val for sublist in [[item]*max(1, remove_from.count(item)-how_many) if item == what else [item]*remove_from.count(item) for item in set(remove_from) & set(remove_from)] for val in sublist]
答案 2 :(得分:0)
如果列表已排序,则有快速解决方案:
def remove_n_duplicates(remove_from, what, how_many):
index = 0
for i in range(len(remove_from)):
if remove_from[i] == what:
index = i
break
if index + how_many >= len(remove_from):
#There aren't enough things to remove.
return
for i in range(index, how_many):
if remove_from[i] != what:
#Again, there aren't enough things to remove
return
endIndex = index + how_many
return remove_from[:index+1] + remove_from[endIndex:]
请注意,这将返回新数组,因此您要执行arr = removeCount(arr,4,3)
答案 3 :(得分:-1)
我可以使用集合以不同的方式解决它。
from collections import Counter
li = [1,2,3,4,4,4,4]
cntLi = Counter(li)
print cntLi.keys()
答案 4 :(得分:-1)
这是另一个可能有用的技巧。不作为推荐配方。
def remove_n_duplicates(remove_from, what, how_many):
exec('remove_from.remove(what);'*how_many)