是否有一个 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?的主要内容,如果未能解决你的问题,请参考以下文章

Python——函数进阶

python实践项目一:Collatz函数

Python3动态添加属性,删除属性,判断属性函数

是否可以在 TypeScript 中传播独特的泛型类型?

python的sorted函数

怎么判断id变量不同python