【发布时间】:2017-12-05 19:59:11
【问题描述】:
在迭代从dict 子类化的对象的键时,我在 Python 3.6.3 中遇到了奇怪的行为。我已经了解 dict.keys() 的行为从 Python 2 更改为 Python 3 以返回 dict_keys 对象,因此看到的浅拷贝行为是可以理解的。我不明白的是为什么 dict_keys 中的元素之一可以通过显式搜索找到,但在迭代 dict_keys 对象时不会出现。
这是 MWE:
#!/usr/bin/env python
from __future__ import print_function
class chemdist(dict):
def normalize_names(self, force_static=False):
if force_static:
raw_chems = tuple(self.keys())
else:
raw_chems = self.keys()
print("raw_chems is " + repr(raw_chems))
if 'Ar' in raw_chems:
print("Found Argon!")
for old_chem in raw_chems:
print("Checking {:s}".format(old_chem))
if old_chem.startswith('_'):
new_chem = old_chem
else:
new_chem = '_' + old_chem
if old_chem != new_chem:
curr_keys = self.keys()
if new_chem in curr_keys:
self[new_chem] += self[old_chem]
else:
self[new_chem] = self[old_chem]
del self[old_chem]
def main():
h_dryair = {
'N2' : 78.084,
'O2' : 20.947,
'Ar' : 0.934,
'CO2' : 0.0350
}
print("Test 1: Not static")
cd_dryair = chemdist(h_dryair)
print(" Unnormalized:")
print(cd_dryair)
print("\n Normalizing:")
cd_dryair.normalize_names()
print("\n Normalized:")
print(cd_dryair)
print("\n\nTest 2: Static")
cd_dryair = chemdist(h_dryair)
print(" Unnormalized:")
print(cd_dryair)
print("\n Normalizing:")
cd_dryair.normalize_names(force_static=True)
print("\n Normalized:")
print(cd_dryair)
main()
结果如下:
Test 1: Not static
Unnormalized:
{'N2': 78.084, 'O2': 20.947, 'Ar': 0.934, 'CO2': 0.035}
Normalizing:
raw_chems is dict_keys(['N2', 'O2', 'Ar', 'CO2'])
Found Argon!
Checking N2
Checking O2
Checking CO2
Checking _N2
Checking _O2
Checking _CO2
Normalized:
{'Ar': 0.934, '_N2': 78.084, '_O2': 20.947, '_CO2': 0.035}
Test 2: Not static
Unnormalized:
{'N2': 78.084, 'O2': 20.947, 'Ar': 0.934, 'CO2': 0.035}
Normalizing:
raw_chems is ('N2', 'O2', 'Ar', 'CO2')
Found Argon!
Checking N2
Checking O2
Checking Ar
Checking CO2
Normalized:
{'_N2': 78.084, '_O2': 20.947, '_Ar': 0.934, '_CO2': 0.035}
在测试 1 中,通过在 raw_chems 中显式搜索找到元素 'Ar'。然而,当迭代raw_chems 时,元素'Ar' 永远不会出现("Checking Ar" 永远不会出现)。
在测试 2 中,raw_chems 被强制转换为元组,"Checking Ar" 按预期出现。
另外,比较最终的标准化对象内容:在测试 1 中,'Ar' 键没有像在测试 2 中那样被替换为 '_Ar'。'Ar' 是测试 1 中唯一没有被替换的键以下划线为前缀。
我对这个问题的原因有两个猜测:dict_keys 有一些对每个人都很明显的行为,或者因为我正在继承 dict 而发生了一些奇怪的事情。可能是两者的结合。
在有人无偿尝试更改我要问的问题之前,我要解决的大问题是将 dict 键重命名为规范形式(HH、H2 和 molecular hydrogen都代表同一件事)。虽然这对于某些人来说可能是一个更有趣的问题,但我问的是消失的键,所以请关注 x ,而不是你想象的 y ... :)
【问题讨论】:
标签: python python-3.x dictionary key