删除列表中连续重复元素的优雅方法? [英] Elegant way to remove contiguous repeated elements in a list?

查看:169
本文介绍了删除列表中连续重复元素的优雅方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种从以下列表中消除的干净的Pythonic方式:

I'm looking for a clean, Pythonic, way to eliminate from the following list:

li = [0, 1, 2, 3, 3, 4, 3, 2, 2, 2, 1, 0, 0]

所有连续的重复元素(运行超过一个数字)以获得:

all contiguous repeated elements (runs longer than one number) so as to obtain:

re = [0, 1, 2, 4, 3, 1]

但是,尽管我有工作代码,但感觉却不是Python风格的,我很确定必须有一种方法(也许是一些鲜为人知的itertools函数?)以更简洁,更优雅的方式实现我想要的功能方式.

but although I have working code, it feels un-Pythonic and I am quite sure there must be a way out there (maybe some lesser known itertools functions?) to achieve what I want in a far more concise and elegant way.

推荐答案

这里是基于Karl的版本,不需要列表的副本(tmp,切片和压缩列表).对于大型列表,izip明显比(Python 2)zip快. chain比切片稍慢一些,但不需要tmp对象或列表副本. islice加上制作tmp的速度稍快一些,但是需要更多的内存并且不够优雅.

Here is a version based on Karl's which doesn't requires copies of the list (tmp, the slices, and the zipped list). izip is significantly faster than (Python 2) zip for large lists. chain is slightly slower than slicing but doesn't require a tmp object or copies of the list. islice plus making a tmp is a bit faster, but requires more memory and is less elegant.

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版本的两倍.

A timeit test shows it to be approximately twice as fast as Karl's or my fastest groupby version for short groups.

如果列表中可以包含None,请确保使用除None之外的其他值(例如object()).

Make sure to use a value other than None (like object()) if your list can contain Nones.

如果您需要使用此版本来处理不是序列的迭代器/可迭代,或者您的组很长,请使用此版本:

Use this version if you need it to work on an iterator / iterable that isn't a sequence, or your groups are long:

[key for key, group in groupby(li) 
        if (next(group) or True) and next(group, None) is None]

timeit显示,对于1,000个项目组,它比另一个版本快大约十倍.

timeit shows it's about ten times faster than the other version for 1,000 item groups.

早期,慢速版本:

[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]

这篇关于删除列表中连续重复元素的优雅方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆