thelist[:] = [d for d in thelist if d.get('id') != 2]
Edit:正如在对此代码性能的评论中表达的一些疑问(有些是基于对 Python 性能特征的误解,有些是基于超出给定规格的假设,即列表中恰好有一个字典的键 'id 的值为 2) ’),我想就这一点提供保证。
在旧的 Linux 机器上,测量以下代码:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(99)]; import random" "thelist=list(lod); random.shuffle(thelist); thelist[:] = [d for d in thelist if d.get('id') != 2]"
10000 loops, best of 3: 82.3 usec per loop
其中 random.shuffle 大约需要 57 微秒(需要确保要删除的元素并不总是在同一位置;-),初始副本大约需要 0.65 微秒(担心 Python 列表浅拷贝的性能影响的人是最担心的)显然是去吃午饭了;-),需要避免改变循环中的原始列表(因此循环的每条腿都有一些要删除的东西;-)。
当知道只有一项需要删除时,可以更迅速地找到并删除它:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(99)]; import random" "thelist=list(lod); random.shuffle(thelist); where=(i for i,d in enumerate(thelist) if d.get('id')==2).next(); del thelist[where]"
10000 loops, best of 3: 72.8 usec per loop
(使用next
内置的而不是.next
当然,如果您使用的是 Python 2.6 或更高版本,则可以使用此方法)——但是如果满足删除条件的字典数量不完全是 1,则此代码会崩溃。概括这一点,我们有:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]"
10000 loops, best of 3: 23.7 usec per loop
正如我们所知,可以删除其中的改组,因为已经有三个等距的字典需要删除。而 listcomp 没有改变,效果很好:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*3; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]"
10000 loops, best of 3: 23.8 usec per loop
完全不相上下,甚至只有 99 个元素中的 3 个元素被删除。对于更长的列表和更多的重复,这当然更有效:
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); where=[i for i,d in enumerate(thelist) if d.get('id')==2]; where.reverse()" "for i in where: del thelist[i]"
1000 loops, best of 3: 1.11 msec per loop
$ python -mtimeit -s"lod=[{'id':i, 'name':'nam%s'%i} for i in range(33)]*133; import random" "thelist=list(lod); thelist[:] = [d for d in thelist if d.get('id') != 2]"
1000 loops, best of 3: 998 usec per loop
总而言之,与完全简单明了的列表理解相比,部署和反转要删除的索引列表的微妙之处显然不值得,因为在一个小情况下可能会获得 100 纳秒,而在较大情况下会损失 113 微秒;-)。避免或批评简单、直接且完全满足性能的解决方案(例如针对“从列表中删除某些项目”这一一般类问题的列表推导式)是 Knuth 和 Hoare 著名论文“过早优化是编程中万恶之源”!-)