我正在尝试从有序列表中删除重复值而不使用IN或SET关键字
我有以下代码,它删除第一次出现重复值,但不删除第二个重复值
def remove_duplicates(list1):
new_list = list(list1)
indx = 0
while indx+1 < len(new_list):
if new_list[indx] == new_list[indx+1] :
new_list.pop(indx)
indx += 1
return new_list
有一个重复它可以工作:
>>> remove_duplicates([1,2,3,3,4])
[1,2,3,4]
但没有三个重复:
>>> remove_duplicates([1,2,3,3,3,4])
[1,2,3,3,4]
据我所知,当您从列表中弹出值时,它也会减小1的大小
任何建议。
答案 0 :(得分:4)
您可以使用filter功能:
>>>uniq = {}
>>>filter(lambda x:uniq.update({x:1}),[1,2,3,3,3,4])
>>> print uniq.keys()
[1, 2, 3, 4]
答案 1 :(得分:3)
>>> dict.fromkeys(lst).keys()
[1, 2, 3, 5]
诀窍是,字典只允许使用唯一键,因此使用具有重复键名的名称创建字典会导致只有一组唯一键。
有值列表:
>>> lst = [1, 1, 1, 2, 3, 3, 5]
我们使用列表值作为键创建一个词典:
>>> dct = dict.fromkeys(lst)
>>> dct
{1: None, 2: None, 3: None, 5: None}
由于所有的关键名称只能出现在:
>>> dct.keys()
[1, 2, 3, 5]
我们有所需要的。
>>> dict.fromkeys(lst).keys()
[1, 2, 3, 5]
我必须承认,即使它没有使用set
,使用dict
密钥也是非常相似的方法。
答案 2 :(得分:2)
>>> def remove_duplicates(iterable):
... last_val = iterable.next()
... yield last_val
... for itm in iterable:
... if itm != last_val:
... last_val = itm
... yield last_val
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> list(remove_duplicates(iter(lst)))
[1, 2, 3, 5]
生成器逐个产生值。
在循环开始之前产生初始值。
remove_duplicates
需要一个可迭代的,因此如果传递一个,则调用需要调用iter(lst)
名单。另一种选择是在发电机内部进行,但我的决定是这样做
外部。
list
in:
list(remove_duplicates(iter(lst)))
是强制生成器产生所有值。
答案 3 :(得分:2)
简而言之:
>>> from itertools import groupby
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> map(lambda grpitm: grpitm[0], groupby(lst))
[1, 2, 3, 5]
一步一步:
>>> from itertools import groupby
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> list(groupby, lst)
[(1, <itertools._grouper at 0x7f759f976a90>),
(2, <itertools._grouper at 0x7f759f976ad0>),
(3, <itertools._grouper at 0x7f759f976b10>),
(5, <itertools._grouper at 0x7f759f976b50>)]
groupby
返回一个迭代器,它产生元组(groupname,grouitemiterator)。
对于我们的任务,我们只关心groupname:
>>> map(lambda grpitm: grpitm[0], groupby(lst))
这将从groupby
返回每个元组,并从中选择第一个元素。
请注意,在Pyhton 3.x中,您必须将map
放入list
才能看到值:
>>> list(map(lambda grpitm: grpitm[0], groupby(lst)))
答案 4 :(得分:1)
轮到我试图解决那个有趣的&#34; Sunday Python拼图&#34; :
>>> def remove_duplicates(lst):
... result = [x for x,n in zip(lst,lst[1:]+[lst[0:1]]) if x != n]
... return result if result or not lst else lst[0:1]
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> print remove_duplicates(lst)
[1, 2, 3, 5]
>>>
>>> lst = [5, 5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = [5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = []
>>> print remove_duplicates(lst)
[]
此答案具有保存原始列表顺序的属性。
有人可能会说我应该使用itertools.izip
。她/他可能是对的。但是,嘿,它的星期天....所以让我们假装我使用Python 3。
答案 5 :(得分:0)
试试这个:
def remove_duplicates(list1):
new_list = list(list1)
indx = 0
while indx+1 < len(new_list):
if new_list[indx] == new_list[indx+1] :
new_list.pop(indx)
else:
indx += 1
return new_list
现在的方式,如果你检测到副本作为三元组的一部分,它将删除中间元素,然后将索引前进到最后一个元素。然后,第一个和最后一个永远不会被比较。这种方式只有在没有检测到重复的情况下才会增加索引。
答案 6 :(得分:0)
我认为这个“星期日拼图游戏”的答案数量没有限制,这是我的第二次尝试。事实上,它应该是第一个,因为这个谜题是reduce
的完美候选者。我不知道我怎么能错过这么久。但是,嘿,现在还是星期天...
>>> def remove_duplicates(lst):
... return reduce(lambda x,n: (x + [n]) if [n] != x[-1:] else x, lst, [])
...
>>> lst = [1, 1, 1, 2, 3, 3, 5]
>>> print remove_duplicates(lst)
[1, 2, 3, 5]
>>>
>>> lst = [5, 5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = [5]
>>> print remove_duplicates(lst)
[5]
>>>
>>> lst = []
>>> print remove_duplicates(lst)
[]