首页 > 解决方案 > 关于切片数组覆盖python中的字典赋值的问题

问题描述

我有以下代码。我正在尝试将 numpy 数组 EPtmp(CH4 用零填充,NO 用 1 填充)添加到字典中,键为“CH4”和“NO”。在 for 循环的第一次迭代中,零数组与键 CH4 正确关联。在第二次迭代中,ones 数组覆盖了先前写入的 CH4 键和新的 NO 键的条目。如果我从 EPtmp[:] = EP 中删除切片,使其改为 EPtmp = EP,它可以完美地工作而不会覆盖先前写入的数组。这似乎与 Python 分配或访问内存的方式有关,但我还没有在文档中找到任何内容来解释这种行为。任何想法为什么切片 [:] 会导致字典覆盖?

  import numpy as np
  species_names = ['O2', 'CH4', 'NO', 'N2', 'O', 'CH3', 'H', 'HO2', 'N2O',     'NO2', 'NNH']
  target_index_species = [1,2]
  EP_spec_dict = {}
  EPtmp = np.zeros(len(species_names),'d')

  for index_target_local, index_target_global in enumerate(target_index_species):
     EP = np.ones(len(species_names))*index_target_local 
     EPtmp[:] = EP
     print("Going to add",species_names[index_target_global],"EP tmp",EPtmp)
     EP_spec_dict[species_names[index_target_global]] = EPtmp
     print("Full dict",EP_spec_dict)

标签: pythonarraysdictionary

解决方案


EPtmp = EP使 EPtmp 成为对 EP 的引用,这意味着如果您更改 EPtmp,您实际上是在更改 EP,因为它们是同一个数组。

EPtmp[:]= EP 复制 EP,因此更改 EPtmp 不会更改 EP。

在您的控制台中尝试以下操作:

a=[1,2]

b=[0,0]

a=b

a[0]=5

b
Out[13]: [5, 0]

a=[1,2]

b=[0,0]

a[:]=b

a[0]=5

b
Out[18]: [0, 0]

但是切片也可以反过来。如果您有b = a然后通过执行 a = [] 设置 a,则 b 不会更改,因为您正在创建一个新的 a。但是,如果您不创建新的 a 而是用 显式覆盖旧的a[:]=[]a ,则 b 会更改。

尝试:

a=[1,2]

b=a

c=b

a=[1,3] #doesn't change b and c

b[:]=[1,4] #changes c

基本上,a=b 意味着 a 是指向 b 指向内存的指针,而 a[:]=b 意味着将 b 的内容写入 a 指向的位置。

因此,在您的示例中,您的字典包含指向 EPtmp 的指针。经过EP_spec_dict[species_names[index_target_global]] = EPtmp

现在,如果您使用 制作一个新的 EPtmp EPtmp=EP,它位于不同的内存部分,并且EP_spec_dict[species_names[index_target_global]]仍然指向旧 EPtmp 的内存部分。但是,使用 EPtmp[:]=EP 您只是覆盖了 EPtmp 的内存内容,而不是创建一个新内容。


推荐阅读