如何在不编辑字典本身的情况下提取和编辑字典值?

How do I extract and edit a dict value without editing the dict itself?

我有一本字典,其中键是字母,值是数组。我想提取其中一个数组,然后从中弹出一个值,而不更改字典。

mydict = {'a': ['apple', 'avocado'], 
          'b': ['banana', 'berry'], 
          'c': ['carrot', 'cucumber']}

fruits = mydict['a']
fruits.pop(0)

当我打印字典时,我得到:

>> {'a': ['avocado'], 'b': ['banana', 'berry'], 'c': ['carrot', 'cucumber']}

如何获取列表的副本,当我从列表中弹出时不会更改字典?

不使用 pop,而是使用索引来获取项目。它将使您的数组完整地保留在 dict 中。

fruit = mydict['a'][0]

在分配 fruit 变量时使用 .copy() 属性。

>>> mydict = {'a': ['apple', 'avocado'], 
              'b': ['banana', 'berry'], 
              'c': ['carrot', 'cucumber']}

>>> fruits = mydict['a'].copy()
>>> fruits.pop(0)

这将给出以下结果

>>> mydict

{'a': ['apple', 'avocado'],
 'b': ['banana', 'berry'],
 'c': ['carrot', 'cucumber']}

>>> fruits

['avocado']

Deep复制:

import copy
fruits = copy.deepcopy(my_dict["a"])

Shallow复制:

import copy
fruits = copy.copy(my_dict["a"])
fruits = my_dict["a"].copy()
fruits = list(my_dict["a"])

由于您所有的元素都是 str 类型,所以浅拷贝列表。 str 对象是不可变的,因此它们的内部状态无法修改。每当你“修改”一个 str 时,你实际上只是制作了一个副本。

More details on deep copying in Python

如果您尝试获取特定值(在本例中为“鳄梨”),并且希望它以列表形式出现,您只需将表达式括在方括号中,它就会变成如下所示的列表:

fruits = [mydict["a"][1]]

=运算符创建了一个新的变量或数据结构,但它基本上指向与以前相同的对象。所以使用 = 运算符将不起作用。

您可以使用 list.copy() 方法,其中 returns 一个 shallow copy 字典中的列表。修改这个列表不会修改原来的字典。

mydict = {'a': ['apple', 'avocado'], 
          'b': ['banana', 'berry'], 
          'c': ['carrot', 'cucumber']}

fruits = mydict['a'].copy()
fruits.pop(0)

print(fruits) # returns ['avocado']
print(mydict) # returns {'a': ['apple', 'avocado'] ...}

或者,使用 Python copy 模块的 copy()deepcopy() 方法都可以。

import copy

mydict = {'a': ['apple', 'avocado'], 
          'b': ['banana', 'berry'], 
          'c': ['carrot', 'cucumber']}

fruits = copy.copy(mydict['a']) # or copy.deepcopy(mydict['a'])
fruits.pop(0)

print(fruits) # returns ['avocado']
print(mydict) # returns {'a': ['apple', 'avocado'] ...}

浅层复制(copy() 方法)和深度复制(deepcopy() 方法)之间的区别很重要,但在这种情况下并不适用,因为您不是在复制 嵌套 数据结构(你的字典),但只是那个字典中的一个列表。

比如浅拷贝dict,修改嵌套list也修改了原来的:

import copy

mydict = {'a': ['apple', 'avocado'], 
          'b': ['banana', 'berry'], 
          'c': ['carrot', 'cucumber']}

fruits = copy.copy(mydict)
fruits['a'].append('apricot') # also changes mydict

print(fruits) # returns {'a': ['apple', 'avocado', 'apricot'] ...}
print(mydict) # also returns {'a': ['apple', 'avocado', 'apricot'] ...}

虽然深度复制没有:

import copy

mydict = {'a': ['apple', 'avocado'], 
          'b': ['banana', 'berry'], 
          'c': ['carrot', 'cucumber']}

fruits = copy.deepcopy(mydict)
fruits['a'].append('apricot') # also changes mydict

print(fruits) # returns {'a': ['apple', 'avocado', 'apricot'] ...}
print(mydict) # returns {'a': ['apple', 'avocado'] ...}

来自复制模块上的Python 3 docs

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.