简体   繁体   English

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

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

It is possible to map a dictionary key to a value that is a reference to a mutable object, such as a list. 可以将字典键映射到作为对可变对象的引用的值,例如列表。 Such a list object can be changed by invoking a list method on the reference, and the changes will be reflected in the dictionary. 可以通过在引用上调用list方法来更改这样的列表对象,并且更改将反映在字典中。 This is discussed in: 这在以下讨论:

My question 我的问题

Is it a good idea to map a dictionary key to the reference of a mutable object as opposed to mapping the key to an unnamed value? 将字典键映射到可变对象的引用是否是一个好主意 ,而不是将键映射到未命名的值?

In other words, it is better to create a dictionary with: 换句话说,最好用以下内容创建字典:

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

or: 要么:

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

And is it better to change a dictionary value though citing that value by reference, eg: 最好通过引用引用该值来更改字典值,例如:

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

or by its dictionary index: 或者通过它的字典索引:

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

Discussion and research 讨论和研究

A reference provides a nice handle that can improve the readability of, say, a function. 引用提供了一个很好的句柄,可以提高功能的可读性。 As far as I can tell, however, the fact that a dictionary value was originally bound to a reference is lost once the value is created; 然而,据我所知,一旦创建了值,字典值最初绑定到引用的事实就会丢失; one cannot see this fact when displaying a dictionary. 在显示字典时,人们看不到这个事实。

On the other hand, I am not sure this matters, because the reference and the value are the same object, and if one deletes the reference, the value object itself remains. 另一方面,我不确定这是否重要,因为引用和值是同一个对象,如果删除引用,则值对象本身仍然存在。

As I see it: 照我看来:

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

In dictionary x , key 'a' maps to value somelist , though I do not see a way to verify that the value is associated with the reference somelist . 在字典x ,键'a'映射到值somelist ,但我没有看到验证该值与引用somelist相关联的somelist

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

This confirms that the list I see as the value is the same as the object pointed to by somelist . 这确认了我看到的值列表与somelist指向的对象相同。

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

Since the value of 'a' in dictionary x is a list, I can remove an item from the list using the list method remove on object x['a'] . 由于字典x'a'的值是一个列表,我可以使用对象x['a']上的列表方法remove列表中的项目。

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

Alternatively, I can use the method remove on object somelist . 或者,我可以在对象somelist上使用remove方法。

In [81]: del somelist

I can delete the reference to the list, but the list object itself remains as the value associated with key a . 我可以删除对列表的引用,但列表对象本身仍然是与键a关联的值。

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

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

As I understand your question, the answer is that it depends what you want to do. 据我了解你的问题,答案是它取决于你想做什么。 If you want to set the dictionary value to an independent copy of some other value, then make a copy. 如果要将字典值设置为某个其他值的独立副本,请进行复制。 If you want to set it to the same object, then don't make a copy. 如果要将其设置为同一对象,则不要复制。

In some cases you may want the dictionary to refer to the same object as other references, because this allows the dictionary to "see" changes to that object. 在某些情况下,您可能希望字典引用与其他引用相同的对象,因为这允许字典“看到”对该对象的更改。 In some cases you may want the dictionary to have its own copy, because you don't want other code that changes the object to affect your dictionary. 在某些情况下,您可能希望字典具有自己的副本,因为您不希望其他更改对象的代码影响您的字典。 It just depends on what the mutable object is and how your code as a whole is using it. 它只取决于可变对象是什么以及您的代码如何使用它。

First, it is fine to use mutable values in a dictionary. 首先,在字典中使用可变值是可以的。 This isn't an anti-pattern. 这不是反模式。 If you don't need to copy a list, then don't. 如果您不需要复制列表,则不要。 It's extra work, so be lazy and don't do it. 这是额外的工作,所以要懒惰,不要这样做。

Second, while there are instances in which I have two references to a mutable object laying around, these seem to be rare. 其次,虽然有些情况下我有两个引用可变对象的参考,但这些似乎很少见。 I'd argue that you want to minimize the number of these cases, because having two different names in the same scope pointing to the same object can potentially be confusing. 我认为你想要最小化这些情况的数量,因为在相同范围内指向同一对象的两个不同的名称可能会令人困惑。 But if you have somelist and x['a'] pointing to the same object, use whichever is clearest. 但是如果你有一些somelistx['a']指向同一个对象,请使用最清楚的那个。 The former will be faster , but not by much, and won't be a huge speed improvement unless written in a tight loop. 前者会更快 ,但不会太多,并且除非以紧密循环书写,否则不会是一个巨大的速度提升。 So go with what reads the best. 那么什么最好去。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将字典与不可散列或不可比较的值进行比较? (例如列表或数据框) - Compare Dictionaries with unhashable or uncomparable values? (e.g. Lists or Dataframes) 在Python环境中自动运行代码生成工具(例如节俭)的最佳实践 - Best practice for automatically running code generation tools (e.g. thrift) in a Python environment Python:参考资料,字典和清单 - Python: References, dictionaries and lists python 中自适应文件路径的最佳方法是什么? 例如使用 pd.read_csv() - What is the best method for an adaptive file path in python? e.g. using pd.read_csv() 在Python中处理项目脚本中的路径/可执行文件的最佳实践(例如Django的manage.py或fabric) - Best practice for handling path/executables in project scripts in Python (e.g. something like Django's manage.py, or fabric) python中any()函数的对立面是什么,例如没有任何 - What is the opposite of any() function in python, e.g. without any 多个嵌套函数需要在 python 中处理连接(例如,使用 MySQLdb 连接到 mysql 服务器)的最佳方法是什么? - What is the best way to handle connections (e.g. to mysql server using MySQLdb) in python, needed by multiple nested functions? 在 function 结束之前退出 python 中的 function (没有返回值)的最佳方法是什么(例如检查失败)? - What is the best way to exit a function (which has no return value) in python before the function ends (e.g. a check fails)? 列表列表的索引的复杂度是多少(例如list [x] [y]) - What is the complexity of index for lists of lists(e.g. list[x][y]) 如何在 Python 中创建 x 列表(例如使用 while 循环)? - How do I create x lists in Python (e.g. with a while-loop)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM