从列表中删除字典 [英] Remove dictionary from list

查看:695
本文介绍了从列表中删除字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有词典列表,请说:

If I have a list of dictionaries, say:

[{'id': 1, 'name': 'paul'},
 {'id': 2, 'name': 'john'}]

并且我想删除id为2(或名称为'john')的字典,以编程方式解决此问题的最有效方法是什么(也就是说,我不知道列表中的条目,因此不能简单地将其弹出.)

and I would like to remove the dictionary with id of 2 (or name 'john'), what is the most efficient way to go about this programmatically (that is to say, I don't know the index of the entry in the list so it can't simply be popped).

推荐答案

thelist[:] = [d for d in thelist if d.get('id') != 2]

编辑:一些评论对此代码的性能表示了怀疑(有些基于对Python的性能特征的误解,有些则假设超出了给定的规范,其中确实有一个要求).该列表的键"id"的值为2),我希望在这一点上可以保证.

Edit: as some doubts have been expressed in a comment about the performance of this code (some based on misunderstanding Python's performance characteristics, some on assuming beyond the given specs that there is exactly one dict in the list with a value of 2 for key 'id'), I wish to offer reassurance on this point.

在旧的Linux机器上,测量以下代码:

On an old Linux box, measuring this code:

$ 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浅表副本的性能影响) list显然是午饭时间;-),需要避免更改循环中的原始列表(因此循环的每一行确实都有一些要删除的东西;-).

of which about 57 microseconds for the random.shuffle (needed to ensure that the element to remove is not ALWAYS at the same spot;-) and 0.65 microseconds for the initial copy (whoever worries about performance impact of shallow copies of Python lists is most obviously out to lunch;-), needed to avoid altering the original list in the loop (so each leg of the loop does have something to delete;-).

当知道只有一个要删除的项目时,可以更快地找到并删除它:

When it is known that there is exactly one item to remove, it's possible to locate and remove it even more expeditiously:

$ 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

(当然,如果您使用的是Python 2.6或更高版本,请使用内置的next而不是.next方法)-但是,如果满足删除条件的字典数量不完全正确,则此代码将分解一.概括地说,我们有:

(use the next builtin rather than the .next method if you're on Python 2.6 or better, of course) -- but this code breaks down if the number of dicts that satisfy the removal condition is not exactly one. Generalizing this, we have:

$ 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保持不变:

where the shuffling can be removed because there are already three equispaced dicts to remove, as we know. And the listcomp, unchanged, fares well:

$ 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个元素将被删除.列表更长且重复次数更多,这当然可以满足更多要求:

totally neck and neck, with even just 3 elements of 99 to be removed. With longer lists and more repetitions, this holds even more of course:

$ 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的著名论点的一个特别讨厌的例子,即过早的优化是编程中所有邪恶的根源!!-)

All in all, it's obviously not worth deploying the subtlety of making and reversing the list of indices to remove, vs the perfectly simple and obvious list comprehension, to possibly gain 100 nanoseconds in one small case -- and lose 113 microseconds in a larger one;-). Avoiding or criticizing simple, straightforward, and perfectly performance-adequate solutions (like list comprehensions for this general class of "remove some items from a list" problems) is a particularly nasty example of Knuth's and Hoare's well-known thesis that "premature optimization is the root of all evil in programming"!-)

这篇关于从列表中删除字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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