<分区>
我正在寻找一种干净的、Pythonic 的方法来从以下列表中删除:
li = [0, 1, 2, 3, 3, 4, 3, 2, 2, 2, 1, 0, 0]
所有连续的重复元素(运行时间超过一个数)以获得:
re = [0, 1, 2, 4, 3, 1]
但是虽然我有工作代码,但感觉不像 Pythonic,而且我很确定一定有办法(也许是一些鲜为人知的 itertools
函数?)来实现我想要的更简洁优雅的方式。
<分区>
我正在寻找一种干净的、Pythonic 的方法来从以下列表中删除:
li = [0, 1, 2, 3, 3, 4, 3, 2, 2, 2, 1, 0, 0]
所有连续的重复元素(运行时间超过一个数)以获得:
re = [0, 1, 2, 4, 3, 1]
但是虽然我有工作代码,但感觉不像 Pythonic,而且我很确定一定有办法(也许是一些鲜为人知的 itertools
函数?)来实现我想要的更简洁优雅的方式。
最佳答案
这是一个基于Karl's answer的版本它不需要列表的副本(tmp
、切片和压缩列表)。对于大型列表,izip
比 (Python 2) zip
快得多。 chain
比切片稍慢,但不需要 tmp
对象或列表的副本。 islice
加上制作 tmp
会更快一些,但需要更多内存并且不够优雅。
from itertools import izip, chain
[y for x, y, z in izip(chain((None, None), li),
chain((None,), li),
li) if x != y != z]
timeit
测试表明它的速度大约是 Karl 的答案或我最快的 groupby
短组版本的两倍。
如果您的列表可以包含 None
,请确保使用 None
以外的值(例如 object()
)。
如果您需要它处理不是序列的迭代器/可迭代对象,或者您的组很长,请使用此版本:
[key for key, group in groupby(li)
if (next(group) or True) and next(group, None) is None]
timeit
显示,对于 1,000 个项目组,它比其他版本快大约十倍。
较早的、较慢的版本:
[key for key, group in groupby(li) if sum(1 for i in group) == 1]
[key for key, group in groupby(li) if len(tuple(group)) == 1]
关于python - 删除列表中连续重复元素的优雅方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7641955/