58

每个学期我至少有一个 Python 学生dict.update()用来添加一个键/值对,即:

mydict.update({'newkey':'newvalue'})

代替

mydict['newkey'] = 'newvalue'

我不教这种方法,也不知道他们在哪里找到这样的例子,但我告诉他们不要这样做,因为它效率较低(可能会创建一个新的 2 元素字典)并且因为它是非标准的。

老实说,我可以理解使用可见方法而不是这种语法的愿望——它可能感觉与其他方法调用更一致。但我认为这看起来像是一种新手方法。

在这一点上,有人可以提供任何智慧吗?

4

3 回答 3

48

基准测试表明您对其性能影响的怀疑似乎是正确的:

$ python -m timeit -s 'd = {"key": "value"}' 'd["key"] = "value"'
10000000 loops, best of 3: 0.0741 usec per loop
$ python -m timeit -s 'd = {"key": "value"}' 'd.update(key="value")'
1000000 loops, best of 3: 0.294 usec per loop
$ python -m timeit -s 'd = {"key": "value"}' 'd.update({"key": "value"})'
1000000 loops, best of 3: 0.461 usec per loop

也就是说,它在我的机器上慢了大约六倍。但是,如果您需要最高性能,Python 已经不是您会使用的语言,所以我只建议使用在这种情况下最易读的语言。对于很多事情来说,这将是[]一种方式,尽管update在这样的情况下可能更具可读性:

configuration.update(
    timeout=60,
    host='example.com',
)

…或类似的东西。

于 2013-03-17T00:09:35.437 回答
10

直接更新密钥的速度是原来的三倍,但是 YMMV:

$ python -m timeit 'd={"k":1}; d.update({"k":2})'
1000000 loops, best of 3: 0.669 usec per loop

$ python -m timeit 'd={"k":1}; d["k"] = 2'
1000000 loops, best of 3: 0.212 usec per loop
于 2013-03-17T00:06:01.107 回答
4

有些人认为 []= 在面向对象语言或任何其他语言中不是有效的句法元素。我记得几十年前我在 APL 语言开发工作时听到过这个论点。该语法是 Fortran 的保留...

我个人并不赞同这种观点,并且对索引分配非常满意。但是有些人会声称真正的方法调用更好。当然,拥有多个解决方案总是好的。

编辑:这里真正的问题是可读性,而不是性能,索引作业一直存在,因为许多人发现作业更容易阅读,即使理论上不太正确。

于 2013-03-17T00:08:27.570 回答