如何根据值更新字典键?
How to update dictionary key based on value?
我有两本字典,它们的值相似,但键不同。我想用第一本字典 user
.
的键值更新第二本字典 db
在不使逻辑过于复杂的情况下,最佳方法是什么?
例如,我有以下词典:
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
user['school']
和 db['education']
具有相同的列表值。我只想将 db
中的键值更新为 user
中的键值。我认为实现方式如下:
def get_key(my_dict, val):
for key, value in my_dict.items():
if val == value:
return key
return None
res = {}
for key, value in db.items():
if value in user.values():
key_user = get_key(user, value)
if key_user:
res.update({key_user: value})
else:
res.update({key: value})
print(res)
我在 Python 3.6.6 中实现了这一点,据我所知,字典条目的顺序得以保留。
所需的输出如下:
{'school': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
如果您为 user
字典创建一个 reverse-loopup dict 可能会更有效率。
逻辑减少到只有 2 行代码:
reverse_user = {tuple(user[key]):key for key in user}
new_db_dict = {reverse_user[tuple(db[db_key])]:db[db_key] for db_key in db if tuple(db[db_key]) in reverse_user}
new_db_dict_excl = {key:db[key] for key in db if tuple(db[key]) not in reverse_user}
new_db_dict.update(new_db_dict_excl)
当我们意识到我们可以用 user
更新整个 db
时,我们可以使它更简单一些。我们需要弄清楚的是在我们更新它之前要删除哪些键,同时还要注意在我们迭代它时不要修改 db
。
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils','sheets','notebooks'],
'actors': ['student','teacher','principal']}
for user_value in user.values():
for del_key in [db_key for db_key, db_value in db.items() if user_value == db_value]:
del db[del_key]
db.update(user)
>>> {'actors': ['student', 'teacher', 'principal'],
'school': ['books', 'pencils', 'sheets', 'notebooks']}
正如您所说,顺序很重要,我认为最简单的方法是 re-create 字典,但对于较大的数据集效率不高。
我们可以迭代db
到re-create它,我们唯一需要看的是使用user
或db
中的密钥。如果密钥存在于 user_values
中,那么我们可以获取它的索引并使用它从 user_keys
中获取密钥,否则我们使用 key
.
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils','sheets','notebooks'],
'actors': ['student','teacher','principal']}
user_keys = tuple(user.keys())
user_values = tuple(user.values())
new_db = {user_keys[user_values.index(value)] if value in user_values else key: value for key, value in db.items()}
>>> {'school': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
我喜欢 Serial Lazer's 有一个颠倒的 dict,但其余部分有点笨拙恕我直言。我会做一个简单的 for-loop 来代替:
x = {'a': [1, 2, 3]} # "user"
y = {'b': [1, 2, 3], 'c': [4, 5, 6]} # "db"
rev = {tuple(v): k for k, v in x.items()}
result = {}
for k, v in y.items():
try:
k = rev[tuple(v)]
except KeyError:
pass
result[k] = v
print(result) # -> {'a': [1, 2, 3], 'c': [4, 5, 6]}
或者你可以使用 ChainMap
如果你可以反转所有的命令,将它们的值转换为元组,然后返回。
from collections import ChainMap
c = ChainMap(*[{tuple(v): k for k, v in d.items()} for d in (x, y)])
result = {v: list(k) for k, v in c.items()}
或者只是一个简单的字典:
x_rev, y_rev = [{tuple(v): k for k, v in d.items()} for d in (x, y)]
y_rev.update(x_rev)
result = {v: list(k) for k, v in y_rev.items()}
我有两本字典,它们的值相似,但键不同。我想用第一本字典 user
.
db
在不使逻辑过于复杂的情况下,最佳方法是什么?
例如,我有以下词典:
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
user['school']
和 db['education']
具有相同的列表值。我只想将 db
中的键值更新为 user
中的键值。我认为实现方式如下:
def get_key(my_dict, val):
for key, value in my_dict.items():
if val == value:
return key
return None
res = {}
for key, value in db.items():
if value in user.values():
key_user = get_key(user, value)
if key_user:
res.update({key_user: value})
else:
res.update({key: value})
print(res)
我在 Python 3.6.6 中实现了这一点,据我所知,字典条目的顺序得以保留。
所需的输出如下:
{'school': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
如果您为 user
字典创建一个 reverse-loopup dict 可能会更有效率。
逻辑减少到只有 2 行代码:
reverse_user = {tuple(user[key]):key for key in user}
new_db_dict = {reverse_user[tuple(db[db_key])]:db[db_key] for db_key in db if tuple(db[db_key]) in reverse_user}
new_db_dict_excl = {key:db[key] for key in db if tuple(db[key]) not in reverse_user}
new_db_dict.update(new_db_dict_excl)
当我们意识到我们可以用 user
更新整个 db
时,我们可以使它更简单一些。我们需要弄清楚的是在我们更新它之前要删除哪些键,同时还要注意在我们迭代它时不要修改 db
。
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils','sheets','notebooks'],
'actors': ['student','teacher','principal']}
for user_value in user.values():
for del_key in [db_key for db_key, db_value in db.items() if user_value == db_value]:
del db[del_key]
db.update(user)
>>> {'actors': ['student', 'teacher', 'principal'],
'school': ['books', 'pencils', 'sheets', 'notebooks']}
正如您所说,顺序很重要,我认为最简单的方法是 re-create 字典,但对于较大的数据集效率不高。
我们可以迭代db
到re-create它,我们唯一需要看的是使用user
或db
中的密钥。如果密钥存在于 user_values
中,那么我们可以获取它的索引并使用它从 user_keys
中获取密钥,否则我们使用 key
.
user = {'school': ['books', 'pencils', 'sheets', 'notebooks']}
db = {'education': ['books', 'pencils','sheets','notebooks'],
'actors': ['student','teacher','principal']}
user_keys = tuple(user.keys())
user_values = tuple(user.values())
new_db = {user_keys[user_values.index(value)] if value in user_values else key: value for key, value in db.items()}
>>> {'school': ['books', 'pencils', 'sheets', 'notebooks'],
'actors': ['student', 'teacher', 'principal']}
我喜欢 Serial Lazer's
x = {'a': [1, 2, 3]} # "user"
y = {'b': [1, 2, 3], 'c': [4, 5, 6]} # "db"
rev = {tuple(v): k for k, v in x.items()}
result = {}
for k, v in y.items():
try:
k = rev[tuple(v)]
except KeyError:
pass
result[k] = v
print(result) # -> {'a': [1, 2, 3], 'c': [4, 5, 6]}
或者你可以使用 ChainMap
如果你可以反转所有的命令,将它们的值转换为元组,然后返回。
from collections import ChainMap
c = ChainMap(*[{tuple(v): k for k, v in d.items()} for d in (x, y)])
result = {v: list(k) for k, v in c.items()}
或者只是一个简单的字典:
x_rev, y_rev = [{tuple(v): k for k, v in d.items()} for d in (x, y)]
y_rev.update(x_rev)
result = {v: list(k) for k, v in y_rev.items()}