如何在列表中找到重复项而不创建单独的列表?
所以,你想一个函数,它接受一个列表,以及该列表仅含有最初复制这些元素发生变异?我假设创建新列表的限制适用于任何新的集合。在提出有关算法的问题时,最好尽可能地明确要求。
这似乎是一个奇怪的要求,在这个算法中没有其他的收集,但它是可能的。 一个简单但低效的解决方案将是接近它是这样的:
- 对于每个元件,
x
- 设置一个布尔标志的值,例如,
hasDuplicates
到false
- 对的每个元素的权利
x
,y
- 如果
y
是x
,再重复移动它,并设置hasDuplicates
到true
- 如果
- 如果
hasDuplicates
是假的,除去x
- 设置一个布尔标志的值,例如,
如果没有创建另一个集合的限制可以放宽,或者如果算法的结果可能是一个新的列表,而不是旧的列表,你会发现更多(时间)有效的方式来做到这一点。
您可以使用set
只得到唯一的值,然后将其删除,一个接一个,从原来的名单 - 因此,只有重复仍将:
a = [1,2,1,3,4,5,4]
s = list(set(a))
for x in s:
a.remove(x)
print a # [1, 4]
另一种优雅的选项,我从Ritesh Kumar“偷”是:
收集只出现一次以上的项目,使用设置删除复本,并与list
包装它返回一个列表的结果:
a = [1,2,1,3,4,5,4]
print list(set([x for x in a if a.count(x) > 1])) # [1, 4]
这应该做你需要什么,除非澄清:
def find_duplicated_items(data):
seen = set()
duplicated = set()
for x in data:
if x in seen:
duplicated.add(x)
else:
seen.add(x)
return duplicated
这需要一个迭代并返回一组;你可以把它变成一个列表list(results)
。
UPDATE:
这里做,作为发电机的另一种方式。只是因为:)。
from collections import Counter
def find_duplicated(iterable, atleast=2):
counter = Counter()
yielded = set()
for item in iterable:
counter[item] += 1
if (counter[item] >= atleast) and (item not in yielded):
yield item
yielded.add(item)
虽然这个问题只是说明没有创建新的'列表',但我会认为要求是没有任何新的收集。此外,它似乎需要一种方法,它改变现有的列表而不是创建一个新的列表。这是完全正确的解决方案,否则我认为! – Oly
@ Oly'Oil'Sourbut - 您能否解释一下创建集合和创建不同列表的不同之处? – nname
计算机科学中的@Nidhi A ['collection'](http://en.wikipedia.org/wiki/Collection_(abstract_data_type))指的是一些相关的数据结构。一个[列表](http://en.wikipedia.org/wiki/List_(abstract_data_type))是一种集合,表示一些有订单的项目,通常可以通过索引访问(例如'a'一个列表,我想'a [4]',第五个 - 从0 - 在'a'中计数)。根据我的经验,[set](http://en.wikipedia.org/wiki/Set_(abstract_data_type))是第二种最常见的集合 - 它存储的数据没有特定的顺序,也没有重复。 – Oly
我会去检查,每个元素,如果它出现在它之前,但不是之后。如果它不合适,那么它不是重复的,或者是您不想保留的副本的其他发生。两种情况我们都不保留。
def simplify(a_list):
for i in range(len(a_list) - 1, -1, -1):
value = a_list[i]
if not value in a_list[:i] or value in a_list[i+1:]:
del a_list[i]
不确定使用切片是否符合您的要求。
用法:
>>> A = [1,2,1,3,4,5,4]
>>> simplify(A)
>>> A
[1, 4]
>>> A = [1,1,1,1,1,2,2,2,2]
>>> simplify(A)
>>> A
[1, 2]
>>> A = [1,1,1,1,1]
>>> simplify(A)
>>> A
[1]
>>> A = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> simplify(A)
>>> A
[]
在python 2我相信'范围(...)'创建一个列表。 – Paul
但是'xrange'没有。 –
此代码出现删除重复2次和非重复的地方,产生含有独特只重复旧的列表。我没有彻底测试它。请注意,所需时间将缩放为O(N ** 2),其中N是输入列表的长度。
与其他解决方案不同,这里没有构建新列表,甚至没有列出for循环或列表理解。
文件: “dup.py”
def dups(mylist):
idx = 0
while(idx<len(mylist)):
delidx = idx+1
ndeleted = 0
while delidx < len(mylist):
if mylist[delidx] == mylist[idx]:
del mylist[delidx]
ndeleted += 1
else:
delidx += 1
if ndeleted==0:
del mylist[idx]
else:
idx += 1
return mylist
用法(IPython中)
In [1]: from dup import dups
In [2]: dups([1,1,1,1,1])
Out[2]: [1]
In [3]: dups([1,1,2,1,1])
Out[3]: [1]
In [4]: dups([1,1,2,2,1])
Out[4]: [1, 2]
In [5]: dups([1,1,2,1,2])
Out[5]: [1, 2]
In [6]: dups([1,2,3,1,2])
Out[6]: [1, 2]
In [7]: dups([1,2,1,3,4,5,4])
Out[7]: [1, 4]
你说的是除去未受骗者还是什么? –
如果原始列表中有三个'4',你想要结果有两个'4'还是一个? – Cyphase
另外,您是否在意订单?结果可以是“[4,1]”吗? – Cyphase