使用 Python 中的字典和列表映射键
Mapping of Keys using dictionary and lists in Python
我有一个字典列表列表,如下所示:
ini_dict = [[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]]
第 1 步:降低一级
我已经修改并降低了一级如下:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
这给了我如下输出:
[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]
第 2 步:用另一个字典中的值替换键
现在,我有另一套 keys 字典 result_dict1
我使用键(此处为小写)将上述数据 mod
中的键替换为相关值(此处为大写)。
result_dict1 = {
"nikhil": "Nikhil",
"vashu": "Vashu",
"manjeet": "Manjeet",
"akshat": "Akshat"
}
我试过的代码
现在,我尝试了下面的代码,但它没有提供我需要的输出:
final = []
for j, k in result_dict1.items():
for i in mod:
for x, y in i.items():
final += [{k: y}]
输出:
[{'Nikhil': 1}, {'Nikhil': 5}, {'Nikhil': 10}, {'Nikhil': 15}, {'Nikhil': 1}, {'Nikhil': 5}, {'Nikhil': 10}, {'Nikhil': 15}, {'Vashu': 1}, {'Vashu': 5}, {'Vashu': 10}, {'Vashu': 15}, {'Vashu': 1}, {'Vashu': 5}, {'Vashu': 10}, {'Vashu': 15}, {'Manjeet': 1}, {'Manjeet': 5}, {'Manjeet': 10}, {'Manjeet': 15}, {'Manjeet': 1}, {'Manjeet': 5}, {'Manjeet': 10}, {'Manjeet': 15}, {'Akshat': 1}, {'Akshat': 5}, {'Akshat': 10}, {'Akshat': 15}, {'Akshat': 1}, {'Akshat': 5}, {'Akshat': 10}, {'Akshat': 15}]
问题
密钥已替换,但组合为 1:N
。
预期输出:
[
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15},
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}
]
您似乎没有检查 mod
中内部字典的键是否与替换字典中的键匹配,这是个问题。
列表理解与字典理解的结果:
>>> [{result_dict1[key]: value for key, value in inner_dict.items()}
for inner_dict in mod]
[{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15},
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}]
因此字典理解正在改变 mod
的内部字典,以便从 result_dict1
替换键。列表理解有助于为每个内部字典执行此操作。
如果 result_dict1
不够全面,这会出错。
上面的理解可以展开为
# this is the final result; we'll fill in this
end_list = []
# foreach dictionary in `mod`...
for inner_dict in mod:
# define anew empty dict
new_inner_dict = {}
# foreach (key, val) pair of the `inner_dict`...
for key, value in inner_dict.items():
# get the `new_key` from the replacer mapping
new_key = result_dict1[key]
# put it into the new dict (but the value is the same)
new_inner_dict[new_key] = value
# above for ended, we have a new_inner_dict; save it
end_list.append(new_inner_dict)
print(end_list)
问题
你快到了:
- 第 1 步:按预期工作
- 第 2 步:遍历键映射
result_dict1
而不是 mod
固定
我在
的地方添加了评论
- 删除循环或将其添加回来稍作修改
- 引入内部集合 (dict) 以保持源分离
ini_dict = [[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]]
# step 2:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
print(f"step 1:\n{mod}")
# step 2:
result_dict1 = {
"nikhil": "Nikhil",
"vashu": "Vashu",
"manjeet": "Manjeet",
"akshat": "Akshat"
}
final = []
# for j, k in result_dict1.items():
for i in mod:
inner = {} # collect inner separately
for x, y in i.items():
k = result_dict1[x] # lookup in dict, instead for-loop
# final += [{k: y}]
inner[k] = y # add to inner (not to final outer) !as dict-entry! (not as list)
final.append(inner) # keep separation
print(f"step 2:\n{final}")
打印:
step 1:
[{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16}, {'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}]
step 2:
[{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 16}, {'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}]
注:
您原来的外部 for 循环 k for j, k in result_dict1.items()
可以重写为:
keys = [k for j, k in result_dict1.items() if j == x] # for-loop as list-comprehension with added conditional
k = keys[0] # key expected as first element in resulting list
相当复杂.. 另外,我们希望找到密钥,但如果列表 keys
为空怎么办?那么 keys[0]
会加注 IndexError: list index out of range
.
最好我们从这里的字典中受益并简化查找:k = result_dict1[x]
建议:命名有帮助
据我所知,变量的命名可以改进。
那么也许这个逻辑缺陷会更早被识别出来。
例如看到 inner
比 i
更有意义。它可以像人类语言一样被阅读和理解——无需在内存中保留名称字典或映射,如“i: inner list or dictionary”作为额外的认知负担。
固定替代
将第 2 步 的当前实现与 第 1 步 的当前实现进行比较:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
print(f"step 1:\n{mod}")
我们也可以在这里重用称为字典理解的模式:
final = []
for i in mod:
final.append({result_dict1[x]: values for x, values in i.items()})
print(f"step 2:\n{final}")
好处:
- 视觉相似性可以识别为形状(即使在大文件中缩小到 10%)
- 它看起来更简单因为熟悉(在我们已经理解了第 1 步之后)
- 更容易识别哪些部分相似(与步骤 1)以及不同之处(例如,没有嵌套级别的 for 循环)
这也称为代码对称。参见例如卡洛斯·布莱 (2014):Code Symmetry
我有一个字典列表列表,如下所示:
ini_dict = [[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]]
第 1 步:降低一级
我已经修改并降低了一级如下:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
这给了我如下输出:
[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]
第 2 步:用另一个字典中的值替换键
现在,我有另一套 keys 字典 result_dict1
我使用键(此处为小写)将上述数据 mod
中的键替换为相关值(此处为大写)。
result_dict1 = {
"nikhil": "Nikhil",
"vashu": "Vashu",
"manjeet": "Manjeet",
"akshat": "Akshat"
}
我试过的代码
现在,我尝试了下面的代码,但它没有提供我需要的输出:
final = []
for j, k in result_dict1.items():
for i in mod:
for x, y in i.items():
final += [{k: y}]
输出:
[{'Nikhil': 1}, {'Nikhil': 5}, {'Nikhil': 10}, {'Nikhil': 15}, {'Nikhil': 1}, {'Nikhil': 5}, {'Nikhil': 10}, {'Nikhil': 15}, {'Vashu': 1}, {'Vashu': 5}, {'Vashu': 10}, {'Vashu': 15}, {'Vashu': 1}, {'Vashu': 5}, {'Vashu': 10}, {'Vashu': 15}, {'Manjeet': 1}, {'Manjeet': 5}, {'Manjeet': 10}, {'Manjeet': 15}, {'Manjeet': 1}, {'Manjeet': 5}, {'Manjeet': 10}, {'Manjeet': 15}, {'Akshat': 1}, {'Akshat': 5}, {'Akshat': 10}, {'Akshat': 15}, {'Akshat': 1}, {'Akshat': 5}, {'Akshat': 10}, {'Akshat': 15}]
问题
密钥已替换,但组合为 1:N
。
预期输出:
[
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15},
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}
]
您似乎没有检查 mod
中内部字典的键是否与替换字典中的键匹配,这是个问题。
列表理解与字典理解的结果:
>>> [{result_dict1[key]: value for key, value in inner_dict.items()}
for inner_dict in mod]
[{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15},
{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}]
因此字典理解正在改变 mod
的内部字典,以便从 result_dict1
替换键。列表理解有助于为每个内部字典执行此操作。
如果 result_dict1
不够全面,这会出错。
上面的理解可以展开为
# this is the final result; we'll fill in this
end_list = []
# foreach dictionary in `mod`...
for inner_dict in mod:
# define anew empty dict
new_inner_dict = {}
# foreach (key, val) pair of the `inner_dict`...
for key, value in inner_dict.items():
# get the `new_key` from the replacer mapping
new_key = result_dict1[key]
# put it into the new dict (but the value is the same)
new_inner_dict[new_key] = value
# above for ended, we have a new_inner_dict; save it
end_list.append(new_inner_dict)
print(end_list)
问题
你快到了:
- 第 1 步:按预期工作
- 第 2 步:遍历键映射
result_dict1
而不是mod
固定
我在
的地方添加了评论- 删除循环或将其添加回来稍作修改
- 引入内部集合 (dict) 以保持源分离
ini_dict = [[
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16},
{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}
]]
# step 2:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
print(f"step 1:\n{mod}")
# step 2:
result_dict1 = {
"nikhil": "Nikhil",
"vashu": "Vashu",
"manjeet": "Manjeet",
"akshat": "Akshat"
}
final = []
# for j, k in result_dict1.items():
for i in mod:
inner = {} # collect inner separately
for x, y in i.items():
k = result_dict1[x] # lookup in dict, instead for-loop
# final += [{k: y}]
inner[k] = y # add to inner (not to final outer) !as dict-entry! (not as list)
final.append(inner) # keep separation
print(f"step 2:\n{final}")
打印:
step 1:
[{'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 16}, {'nikhil': 1, 'vashu': 5, 'manjeet': 10, 'akshat': 15}]
step 2:
[{'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 16}, {'Nikhil': 1, 'Vashu': 5, 'Manjeet': 10, 'Akshat': 15}]
注:
您原来的外部 for 循环 k for j, k in result_dict1.items()
可以重写为:
keys = [k for j, k in result_dict1.items() if j == x] # for-loop as list-comprehension with added conditional
k = keys[0] # key expected as first element in resulting list
相当复杂.. 另外,我们希望找到密钥,但如果列表 keys
为空怎么办?那么 keys[0]
会加注 IndexError: list index out of range
.
最好我们从这里的字典中受益并简化查找:k = result_dict1[x]
建议:命名有帮助
据我所知,变量的命名可以改进。 那么也许这个逻辑缺陷会更早被识别出来。
例如看到 inner
比 i
更有意义。它可以像人类语言一样被阅读和理解——无需在内存中保留名称字典或映射,如“i: inner list or dictionary”作为额外的认知负担。
固定替代
将第 2 步 的当前实现与 第 1 步 的当前实现进行比较:
mod = []
for i in ini_dict:
for j in i:
mod.append({item: values for item, values in j.items()})
print(f"step 1:\n{mod}")
我们也可以在这里重用称为字典理解的模式:
final = []
for i in mod:
final.append({result_dict1[x]: values for x, values in i.items()})
print(f"step 2:\n{final}")
好处:
- 视觉相似性可以识别为形状(即使在大文件中缩小到 10%)
- 它看起来更简单因为熟悉(在我们已经理解了第 1 步之后)
- 更容易识别哪些部分相似(与步骤 1)以及不同之处(例如,没有嵌套级别的 for 循环)
这也称为代码对称。参见例如卡洛斯·布莱 (2014):Code Symmetry