在Python词典中引用mutable(例如,列表)作为值 - 什么是最佳实践?

Tom*_*ker 9 python dictionary list

可以将字典键映射到作为对可变对象的引用的值,例如列表.可以通过在引用上调用list方法来更改这样的列表对象,并且更改将反映在字典中.这在以下讨论:

我的问题

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

换句话说,最好用以下内容创建字典:

In [74]: x = {'a': somelist}
Run Code Online (Sandbox Code Playgroud)

要么:

In [74]: x = {'a': somelist[:]}
Run Code Online (Sandbox Code Playgroud)

最好通过引用引用该值来更改字典值,例如:

In [77]: somelist.remove('apples')
Run Code Online (Sandbox Code Playgroud)

或者通过它的字典索引:

In [77]: x['a'].remove('apples')
Run Code Online (Sandbox Code Playgroud)

讨论和研究

引用提供了一个很好的句柄,可以提高功能的可读性.然而,据我所知,一旦创建了值,字典值最初绑定到引用的事实就会丢失; 在显示字典时,人们看不到这个事实.

另一方面,我不确定这是否重要,因为引用和值是同一个对象,如果删除引用,则值对象本身仍然存在.

照我看来:

In [73]: somelist = ['apples', 'oranges', 'lemons', 'tangerines']
In [74]: x = {'a': somelist}
In [75]: x
Out[75]: {'a': ['apples', 'oranges', 'lemons', 'tangerines']}
Run Code Online (Sandbox Code Playgroud)

在字典中x,键'a'映射到值somelist,但我没有看到验证该值与引用相关联的方法 somelist.

In [76]: x['a'] is somelist
Out[76]: True
Run Code Online (Sandbox Code Playgroud)

这确认了我看到的值列表与指向的对象相同somelist.

In [77]: x['a'].remove('apples')
In [78]: x
Out[78]: {'a': ['oranges', 'lemons', 'tangerines']}
Run Code Online (Sandbox Code Playgroud)

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

In [79]: somelist.remove('lemons')
In [80]: x
Out[80]: {'a': ['oranges', 'tangerines']}
Run Code Online (Sandbox Code Playgroud)

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

In [81]: del somelist
Run Code Online (Sandbox Code Playgroud)

我可以删除对列表的引用,但列表对象本身仍然是与key关联的值a.

In [82]: x['a'].remove('oranges')

In [83]: x
Out[83]: {'a': ['tangerines']}
Run Code Online (Sandbox Code Playgroud)

Bre*_*arn 4

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

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