根据所选键比较 2 个字典列表,无需 for 循环
Compare 2 list of dictionnary based on selected key without for loop
假设我有这 2 个字典列表:
Dict1=[
{"name": "James","age": "21"},
{"name": "Evelyn","age": "28"},
{"name": "William","age": "31"}
]
Dict2=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"M"},
{"name": "Ella","age": "17","city":"NYC","Gender":"F"}
]
如何仅根据名称键比较它们并从 dict2 中获取整个条目,在这种情况下,结果必须是:
new_dict=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"F"},
]
我正在寻找一种方法来根据一个或多个选定的键进行比较,而不使用 for 循环。
有点复杂,但您可以使用 pandas 来避免使用循环:
import pandas as pd
Dict1=[
{"name": "James","age": "21"},
{"name": "Evelyn","age": "28"},
{"name": "William","age": "31"}
]
Dict2=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"M"},
{"name": "Ella","age": "17","city":"NYC","Gender":"F"}
]
df1 = pd.DataFrame(Dict1)
df2 = pd.DataFrame(Dict2)
df = df2[df2['name'].isin(df1['name'])]
print(df.to_dict(orient="records"))
输出:
[{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'}, {'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}]
没有循环你想做的事是不可能的。您最终可以通过使用库或复杂的方式隐藏循环,但最简单的是循环。
现在有不好的方式和好的方式循环。不好的是检查 Dict1 的每个元素是否为 Dict2 的每个元素(O(n*m) 复杂度)。
一个好的方法是为 Dict1 中的名称构造一个 set
索引,并使用它们来匹配 Dict2 中的名称:
names = set(d['name'] for d in Dict1)
new_dict = [d for d in Dict2 if d['name'] in names]
输出:
>>> new_dict
[{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'},
{'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}]
- 为清楚起见,您将列表命名为“Dicts”。将来可能会造成混淆。
- 假设名称是唯一的,您可以像这样使用字典:
d1 = {person['name']: person for person in Dict1}
d2 = {person['name']: person for person in Dict2}
result = [person for name, person in d2.items() if name in d1]
# result is:
[
{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'},
{'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}
]
还有其他方法可以实现,有些甚至更有效,但如果您需要可读性,这可能会有所帮助。
编辑:这显然使用了循环,但是如果不遍历集合就无法完成您的请求。所以我假设你只是想避免 for
块。
假设我有这 2 个字典列表:
Dict1=[
{"name": "James","age": "21"},
{"name": "Evelyn","age": "28"},
{"name": "William","age": "31"}
]
Dict2=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"M"},
{"name": "Ella","age": "17","city":"NYC","Gender":"F"}
]
如何仅根据名称键比较它们并从 dict2 中获取整个条目,在这种情况下,结果必须是:
new_dict=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"F"},
]
我正在寻找一种方法来根据一个或多个选定的键进行比较,而不使用 for 循环。
有点复杂,但您可以使用 pandas 来避免使用循环:
import pandas as pd
Dict1=[
{"name": "James","age": "21"},
{"name": "Evelyn","age": "28"},
{"name": "William","age": "31"}
]
Dict2=[
{"name": "James","age": "21","city":"NYC","Gender":"M"},
{"name": "William","age": "25","city":"NYC","Gender":"M"},
{"name": "Ella","age": "17","city":"NYC","Gender":"F"}
]
df1 = pd.DataFrame(Dict1)
df2 = pd.DataFrame(Dict2)
df = df2[df2['name'].isin(df1['name'])]
print(df.to_dict(orient="records"))
输出:
[{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'}, {'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}]
没有循环你想做的事是不可能的。您最终可以通过使用库或复杂的方式隐藏循环,但最简单的是循环。
现在有不好的方式和好的方式循环。不好的是检查 Dict1 的每个元素是否为 Dict2 的每个元素(O(n*m) 复杂度)。
一个好的方法是为 Dict1 中的名称构造一个 set
索引,并使用它们来匹配 Dict2 中的名称:
names = set(d['name'] for d in Dict1)
new_dict = [d for d in Dict2 if d['name'] in names]
输出:
>>> new_dict
[{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'},
{'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}]
- 为清楚起见,您将列表命名为“Dicts”。将来可能会造成混淆。
- 假设名称是唯一的,您可以像这样使用字典:
d1 = {person['name']: person for person in Dict1}
d2 = {person['name']: person for person in Dict2}
result = [person for name, person in d2.items() if name in d1]
# result is:
[
{'name': 'James', 'age': '21', 'city': 'NYC', 'Gender': 'M'},
{'name': 'William', 'age': '25', 'city': 'NYC', 'Gender': 'M'}
]
还有其他方法可以实现,有些甚至更有效,但如果您需要可读性,这可能会有所帮助。
编辑:这显然使用了循环,但是如果不遍历集合就无法完成您的请求。所以我假设你只是想避免 for
块。