我有一本字典,里面的键是单个字符。我想用它们的双重版本来替换大写字符。
例如,我有这样的结构:
x = 'AbCDEfGH'
a = dict(zip(list(x), range(len(x))))
print(a)
它创建了这个字典:
{'A': 0, 'b': 1, 'C': 2, 'D': 3, 'E': 4, 'f': 5, 'G': 6, 'H': 7}
值无关紧要,所以我只使用一些整数。我想要的是用双字符替换大写键,这样我就得到了:
{'AA': 0, 'b': 1, 'CC': 2, 'DD': 3, 'EE': 4, 'f': 5, 'GG': 6, 'HH': 7}
因此,我尝试了以下就地替换:
for k, v in a.items():
if k.isupper():
a[k+k] = a.pop(k)
print(a)
但奇怪的是,这导致了:
{'b': 1, 'E': 4, 'f': 5, 'G': 6, 'CCCCCCCCCCCCCCCC': 2, 'DDDDDDDDDDDDDDDD': 3, 'HHHHHHHHHHHHHHHH': 7, 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 0}
更奇怪的是,如果我将所有键都设置为大写:
y = 'ABCDEFGH'
a = dict(zip(list(y), range(len(y))))
for k, v in a.items():
if k.isupper():
a[k+k] = a.pop(k)
print(a)
它产生:
{'D': 3, 'E': 4, 'F': 5, 'CCCCCCCC': 2, 'GGGGGGGG': 6, 'HHHHHHHH': 7, 'AAAAAAAAAAAAAAAA': 0, 'BBBBBBBBBBBBBBBB': 1}
- 发生了什么?我看到这些键的大小是2。但是,为什么
- 我真的不在乎这些物品的顺序,但我看到有些甚至没有改变
- 有没有其他方法可以像我打算的那样替换钥匙
.items()
返回底层dict
内容的实时视图。在迭代dict
时对其进行突变会导致不可预测的效果,通常会导致某些密钥被处理多次(因此某些密钥会加倍(,而其他密钥则根本不被处理。如果dict
在迭代过程中改变了大小,Python试图通过引发RuntimeError
来保护您,但您的代码在检查时(当从迭代器请求下一项时(保持不变的大小,因此Python的廉价长度检查并不能拯救您。
最小的修复方法是使循环在items
:的快照上运行
for k, v in tuple(a.items()):
一个更简单的解决方案是dict
理解:
a = {k*2 if k.isupper() else k: v for k, v in a.items()}
这将在重新分配a
之前使用双密钥构建一个全新的dict
,因此不会出现突变问题。就这一点而言,你可以一下子构建a
,只需执行以下操作:
a = {let*2 if let.isupper() else let: i for i, let in enumerate(x)}
无需list
验证x
(字符串已经按字符迭代(,enumerate
可以为您的值编号,而根本不需要zip
、range
或len
。