使用 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]

建议:命名有帮助

据我所知,变量的命名可以改进。 那么也许这个逻辑缺陷会更早被识别出来。

例如看到 inneri 更有意义。它可以像人类语言一样被阅读和理解——无需在内存中保留名称字典或映射,如“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