是否有一个 python 函数可以返回一个添加了新键的新字典,比如 clojure 中的 assoc?
Posted
技术标签:
【中文标题】是否有一个 python 函数可以返回一个添加了新键的新字典,比如 clojure 中的 assoc?【英文标题】:Is there a python function to return a new dict with a new key added, like assoc in clojure? 【发布时间】:2018-03-20 17:46:39 【问题描述】:我在写了一段时间的 clojure 之后正在写 python,我有点生疏,但我正在以一种更实用的风格来接近它。为了遵循我在 clojure 中使用的模式,我想使用带有 assoc 之类的映射(或列表理解)来设置列表中每个字典的键。
我有一个记录列表,我想用列表解析来重构它们。
记录如下:
"timestamp":1232435235315,
"data":
"foo": 2345,
"bar": 1454
我想从数据中获取一个包含时间戳和键的字典。
newlist = [ assoc(x, "timestamp", x["timestamp"]) for x in mylist ]
我可以很容易地实现一个 assoc,但我希望它已经存在于一个库中:
def assoc(coll, k, v):
newcoll = coll.copy()
newcoll[k] = v
return newcoll
有没有人知道一个已经包含类似这样的东西的库,或者在不改变原始列表的情况下简洁地做到这一点的pythonic方式?
【问题讨论】:
不,但是如果有人有一个库,它会建立一个模式,并且其中可能有其他类似有用的功能。我不介意在clojure.core 中有很多东西的pythonic 版本。我可以编写这样一个库,但如果其他人已经拥有一个,我不想重新发明***。 【参考方案1】:当然,你可以简单地使用dict()
,例如:
old = "a": 1
new_one = dict(old, new_key=value)
#or
new_one = dict(old, ...)
【讨论】:
对此要注意的一点是它不会深度复制值,因此任何引用都将在两个字典之间共享。 是的,感谢@ryachza。如果你真的想要一个深拷贝,你可以使用from copy import deepcopy
然后new_one = deepcopy(dict(old, new_key=value))
。
这段代码依赖python版本吗?在 python 3.9.0 中,评估 dict(, 1 : 3)
结果为 TypeError: dict expected at most 1 argument, got 2
。
@Hi-Angel 请注意您回复的答案如何使用关键字参数
@Hi-Angel 在 python 3 中,需要内部字典之前的双星:new_one = dict(old, **...)
。但是在 python 3.9 中,字典合并更容易,正如 syltruong 在另一个答案中所说的那样【参考方案2】:
从 Python 3.9 开始,您也可以使用 Dictionary Merge and Update Operators,尽管有些人可能认为这不太明确。
代码 sn-p 将变为:
old = "a": 1
# 1. Merge operator
new_one = old | "new_key": value
## `old_one` is "a": 1
## `new_one` is "a": 1, "new_key": value
# 2. Update operator
old |= "new_key": value
## `old_one` becomes "a": 1, "new_key": value
【讨论】:
【参考方案3】:对我来说,接受的答案抛出
TypeError: dict 最多需要 1 个参数,得到 2 个
如果由于某种原因不能使用 Python 3.9,可以定义如下所示的函数
def dict_update(x, **kwargs):
y = x.copy()
y.update(kwargs)
return y
old = "a", 1
new = dict_update(old, b=2, c=3)
print(old)
>>> "a": 1
print(new)
>>> "a": 1, "b": 2, "c": 3
【讨论】:
此解决方案还将更新old
,我认为问题作者并不想要。
感谢@Conchylicultor 的评论编辑了答案【参考方案4】:
如果您希望它具有与 Clojure 中类似的性能特征,PEP 603 (draft) 似乎是前进的方向。截至 2021 年初,此 PEP 不被接受,但存在完整实施:https://github.com/MagicStack/immutables
【讨论】:
以上是关于是否有一个 python 函数可以返回一个添加了新键的新字典,比如 clojure 中的 assoc?的主要内容,如果未能解决你的问题,请参考以下文章