[英]Transform Python dictionary from {'a': ['A', 'B'], 'b': ['B', 'C']} --> {'A': ['a'], 'B': ['a', 'b'], 'C': ['b']}
我从这本词典开始:
lower_to_upper = {"a": ["A", "B"],
"b": ["B", "C"]}
然后,我将所有大写字母放在一个列表中并打印该列表...
upper_list = [upper for lo_uppers in lower_to_upper.values() for upper in lo_uppers]
print(f"upper_list: {upper_list}")
...正如预期的那样:
upper_list: ['A', 'B', 'B', 'C']
接下来,我根据大写字母列表创建两个字典。 一个有零作为值( upper_to_count
)和另一个有空列表的是它的值( upper_to_lower
):
upper_to_count = dict.fromkeys(upper_list, 0)
upper_to_lower = dict.fromkeys(upper_list, [])
接下来,我想让upper_to_count
包含原始字典中出现大写字母的条目数。 同样,我想在upper_to_lower
填充 - 现在 - 空列表,其中小写字符串是它们各自大写字母的键。
for i, upper_list in enumerate(lower_to_upper.values()):
lower = list(lower_to_upper.keys())[i]
for upper in upper_list:
upper_to_count[upper] += 1
upper_to_lower[upper].append(lower)
upper_to_count
的结果符合预期。 但是upper_to_lower
的结果并不像 (I) 预期的那样。 这些说法...
print(f"upper_to_count: {upper_to_count}")
print(f"upper_to_lower: {upper_to_lower}")
... 打印:
upper_to_count: {'A': 1, 'B': 2, 'C': 1}
upper_to_lower: {'A': ['a', 'a', 'b', 'b'], 'B': ['a', 'a', 'b', 'b'], 'C': ['a', 'a', 'b', 'b']}
我的期望是这样的:
print(f"upper_to_lower_exp: {upper_to_lower_exp}")
upper_to_lower_exp: {'A': ['a'], 'B': ['a', 'b'], 'C': ['b']}
这是一本看起来像这样的字典:
upper_to_lower_exp = {'A': ['a'],
'B': ['a', 'b'],
'C': ['b']}
我不明白为什么我得到upper_to_lower
而不是upper_to_lower_exp
。 我不知道是什么产生了upper_to_lower
而不是upper_to_lower_exp
的输出?
我为我的问题标题的奇怪而道歉。 非常感谢您提前提供任何帮助!
不确定你是如何初始化upper_to_lower
字典的,但是如果像这样初始化,你的代码可以正常工作:
# `list(set(upper_list))` being ['A', 'B', 'C']
upper_to_lower = {k: [] for k in list(set(upper_list))}
for i, upper_list in enumerate(lower_to_upper.values()):
lower = list(lower_to_upper.keys())[i]
for upper in upper_list:
upper_to_count[upper] += 1
upper_to_lower[upper].append(lower)
输出:
{'B': ['a', 'b'], 'A': ['a'], 'C': ['b']}
当并行迭代键和值时,最佳实践是使用.items
:
lower_to_upper = {"a": ["A", "B"],
"b": ["B", "C"]}
upper_to_lower_exp = {}
for key, values in lower_to_upper.items():
# iterate over each value
for value in values:
# if no key has been created so far for the value create one
if value not in upper_to_lower_exp:
upper_to_lower_exp[value] = []
# append the key to the list of the corresponding value
upper_to_lower_exp[value].append(key)
# upper_to_count is just upper_to_lower_exp but with the length of the lists instead
upper_to_count = {k: len(vs) for k, vs in upper_to_lower_exp.items()}
print(upper_to_count)
print(upper_to_lower_exp)
输出
{'A': 1, 'B': 2, 'C': 1}
{'A': ['a'], 'B': ['a', 'b'], 'C': ['b']}
我找到了答案。 在官方文档中,关键的花絮是初始化字典的值“只引用一个实例”——是None
或例如一个空列表。 因此,当我将元素附加到这个列表时,最终字典中的所有键都将指向同一个列表。
classmethod fromkeys ( iterable [, value ]) 使用 iterable 中的键和值设置为值创建一个新字典。
fromkeys() 是一个返回新字典的类方法。 值默认为无。 所有的值都只引用一个实例,因此将值作为可变对象(例如空列表)通常没有意义。 要获得不同的值,请改用字典理解。 ( 在此处输入链接描述)
我不知道。 非常感谢提供的答案!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.