嗯,很绕的标题,但是这是为了解决这样一个问题:存在一个python列表,这个列表是由一系列的同样类型的字典组成,想要对该列表中的每一个字典进行更新(按照一定规则),并返回一个新的列表。
如此假定:
1 | In [1]: d = [ # 原始列表 |
使用最简单的方法就是,新建一个空列表,使用for循环遍历已有的字典列表,并对每个字典进行更新后添加进新建的空列表中。如下代码示意
1 | In [3]: d_1 = [] |
那有没有其他的方法馁,这就是本篇文章探讨了。。(最近奇技淫巧想多了。
就想用列表推导式来解决(毕竟如In[3] 的结构很容易改写成列表推导式)
1 | In [4]: [i.update({"new_id": i["id"] + 1}) for i in d] |
然而却得到了这样的结果?为什么馁。
查看官方文档dict.update
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.
update() accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then updated with those key/value pairs: d.update(red=1, blue=2).
好吧,dict.update返回的是None。那换个思路(对,上stackoverflow找找。
然后就看到了这篇python - update dict in list comprehension - Stack Overflow
来,我们来尝试下
1 | In [5]: [{i:j for i,j in t.items() + [("new_id",t["id"]+1)]} for t in d] |
什么鬼嘛(摔 ,怪不得是0赞0踩的答案。直接抛出了TypeError。
原来,在python3中,dict.items()不像py2中一样返回一个列表,而是返回了一个dict_items对象。(参见2.7#dict.items 以及 3.6#dict.items )
items()
Python2.7 : Return a copy of the dictionary’s list of (key, value) pairs.
Python3.6 : Return a new view of the dictionary’s items ((key, value) pairs).
这都不行,那也不行,那lambda。。 也不行。。。就在我想要放弃的时候
我神tm的想出了一个方法。
你update不是不返回吗,但是实际上字典列表中的字典已经更新了,那用or来过滤掉就行。就有了以下的列表推导式。
在执行的过程中因为 None or i => i让推导式中生成值为i。
1 | In [6]: [i.update({"new_id": i["id"] + 1}) or i for i in d] |
