关于将变量(例如,列表)引用为Python词典中的值:引用变量(例如,列表)作为Python词典中的值 – 什么是最佳实践?

References to mutables (e.g., lists) as values in Python dictionaries - what is best practice?

可以将字典键映射到引用可变对象,如列表。这样的列表对象可以通过调用引用上的列表方法,这些更改将反映在字典。讨论内容如下:

  • python:如何通过引用传递变量?和
  • python:变量什么时候通过引用传递,什么时候通过值传递?

我的问题

将字典键映射到变量的引用是个好主意吗对象,而不是将键映射到未命名的值?

换句话说,它最好创建字典:

1
In [74]: x = {'a': somelist}

或:

1
In [74]: x = {'a': somelist[:]}

如果引用字典的值,那么修改字典的值更好吗?通过引用,例如:

1
In [77]: somelist.remove('apples')

或者根据字典索引:

1
In [77]: x['a'].remove('apples')

讨论和研究

引用提供了一个很好的句柄,可以提高功能。然而,据我所知,字典值是创建值后,最初绑定到引用的值将丢失;不能在显示词典时查看此事实。

另一方面,我不确定这一点,因为参考文献和值是相同的对象,如果删除引用,则值对象它本身依然存在。

正如我看到的:

1
2
3
4
In [73]: somelist = ['apples', 'oranges', 'lemons', 'tangerines']
In [74]: x = {'a': somelist}
In [75]: x
Out[75]: {'a': ['apples', 'oranges', 'lemons', 'tangerines']}

在字典x中,键'a'映射到值somelist,尽管我没有查看验证值是否与引用关联的方法somelist

1
2
In [76]: x['a'] is somelist
Out[76]: True

这确认了我所看到的值与对象相同的列表由somelist指出。

1
2
3
In [77]: x['a'].remove('apples')
In [78]: x
Out[78]: {'a': ['oranges', 'lemons', 'tangerines']}

因为字典x'a'的值是一个列表,所以我可以删除一个项目。从列表中使用对象x['a']上的列表方法remove

1
2
3
In [79]: somelist.remove('lemons')
In [80]: x
Out[80]: {'a': ['oranges', 'tangerines']}

或者,我可以在对象somelist上使用方法remove

1
In [81]: del somelist

我可以删除对列表的引用,但列表对象本身仍然保留与键a关联的值。

1
2
3
4
In [82]: x['a'].remove('oranges')

In [83]: x
Out[83]: {'a': ['tangerines']}


我理解你的问题,答案是这取决于你想做什么。如果要将字典值设置为某个其他值的独立副本,请制作副本。如果要将其设置为同一对象,则不要复制。

在某些情况下,您可能希望字典引用与其他引用相同的对象,因为这允许字典"查看"对该对象的更改。在某些情况下,您可能希望字典有自己的副本,因为您不希望更改对象以影响字典的其他代码。它仅仅取决于可变对象是什么,以及整个代码如何使用它。


首先,可以在字典中使用可变值。这不是反模式。如果你不需要复制一个列表,那就不要复制。这是额外的工作,所以要懒惰,不要做。

第二,虽然在某些情况下,我有两个对周围可变对象的引用,但这些引用似乎很少。我认为您希望最小化这些情况的数量,因为在同一范围内有两个不同的名称指向同一对象可能会造成混淆。但如果你的somelistx['a']指向同一个物体,使用最清楚的。前者会更快,但不会太快,除非写在一个紧密的循环中,否则不会有很大的速度改进。所以,跟着读得最好的东西走吧。