这里介绍一种传统的方法,即在向后遍历列表时,在原地删除相邻重复项:
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> def dedupe_adjacent(alist):
... for i in xrange(len(alist) - 1, 0, -1):
... if alist[i] == alist[i-1]:
... del alist[i]
...
>>> data = [1,2,2,3,2,2,4]; dedupe_adjacent(data); print data
[1, 2, 3, 2, 4]
>>> data = []; dedupe_adjacent(data); print data
[]
>>> data = [2]; dedupe_adjacent(data); print data
[2]
>>> data = [2,2]; dedupe_adjacent(data); print data
[2]
>>> data = [2,3]; dedupe_adjacent(data); print data
[2, 3]
>>> data = [2,2,2,2,2]; dedupe_adjacent(data); print data
[2]
>>>
更新:如果您需要一个生成器但是(没有itertools.groupby
或者(您打字的速度比阅读其文档并理解其默认行为更快),这里有一个六行代码的函数可以做到:
Python 2.3.5 (
Type "help", "copyright", "credits" or "license" for more information.
>>> def dedupe_adjacent(iterable):
... prev = object()
... for item in iterable:
... if item != prev:
... prev = item
... yield item
...
>>> data = [1,2,2,3,2,2,4]; print list(dedupe_adjacent(data))
[1, 2, 3, 2, 4]
>>>
更新2: 关于巴洛克风格的 itertools.groupby()
和极简主义的 object()
...
要从 itertools.groupby()
中获取去重相邻项的效果,您需要在其周围包装一个列表推导式,以丢弃不需要的分组器:
>>> [k for k, g in itertools.groupby([1,2,2,3,2,2,4])]
[1, 2, 3, 2, 4]
>>>
如果需要的话,你可以使用 itertools.imap
和/或 operators.itemgetter
,就像另一个答案中所看到的那样。
对于 object
实例的预期行为是,它们都不等于任何其他类的实例,包括 object
本身。因此,它们非常适用于作为哨兵。
>>> object() == object()
False
值得注意的是,
itertools.groupby
的
Python参考代码使用
object()
作为标记对象:
self.tgtkey = self.currkey = self.currvalue = object()
并且当您运行该代码时,它将执行正确的操作:
>>> data = [object(), object()]
>>> data
[<object object at 0x00BBF098>, <object object at 0x00BBF050>]
>>> [k for k, g in groupby(data)]
[<object object at 0x00BBF098>, <object object at 0x00BBF050>]
更新3: 关于前向索引原地操作的说明
原帖作者修改后的代码:
def remove_adjacent(nums):
i = 1
while i < len(nums):
if nums[i] == nums[i-1]:
nums.pop(i)
i -= 1
i += 1
return nums
最好写成:
def remove_adjacent(seq):
i = 1
n = len(seq)
while i < n:
if seq[i] == seq[i-1]:
del seq[i]
n -= 1
else:
i += 1
<>
,正确的表示法是!=
。使用if a
,而不是if len(a) <> 0
。 - Katriel