更改字典中键的名称
Posted
技术标签:
【中文标题】更改字典中键的名称【英文标题】:Change the name of a key in dictionary 【发布时间】:2011-05-23 07:59:23 【问题描述】:我想更改 Python 字典中条目的键。
有没有直接的方法来做到这一点?
【问题讨论】:
【参考方案1】:两步轻松搞定:
dictionary[new_key] = dictionary[old_key]
del dictionary[old_key]
或在 1 步中:
dictionary[new_key] = dictionary.pop(old_key)
如果dictionary[old_key]
未定义,这将引发KeyError
。请注意,这将删除dictionary[old_key]
。
>>> dictionary = 1: 'one', 2:'two', 3:'three'
>>> dictionary['ONE'] = dictionary.pop(1)
>>> dictionary
2: 'two', 3: 'three', 'ONE': 'one'
>>> dictionary['ONE'] = dictionary.pop(1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 1
【讨论】:
如果密钥不存在,这将引发 KeyError,但您可以使用dict[new_value] = dict.pop(old_value, some_default_value)
来避免这种情况
请注意,这也会影响 CPython 3.6+ / Pypy 和 Python 3.7+ 中键的位置。也就是说一般old_key
的位置会和new_key
的位置不同。
@TobiasKienzler 但是请注意不要将dict
用作变量名。
我这样做的经验是,您最好使用字典理解从现有字典创建一个新字典(根据下面沃德的回答)。如果我尝试遍历现有字典并更改键,我会得到不同的结果(例如,有时它会起作用,而其他时候会引发运行时错误)。
当有多个同名键时,一个衬里是更好的选择【参考方案2】:
如果你想改变所有的键:
d = 'x':1, 'y':2, 'z':3
d1 = 'x':'a', 'y':'b', 'z':'c'
In [10]: dict((d1[key], value) for (key, value) in d.items())
Out[10]: 'a': 1, 'b': 2, 'c': 3
如果你想改变单键: 您可以接受上述任何建议。
【讨论】:
这会创建一个新字典,而不是更新现有字典——这可能并不重要,但不是所要求的。 与字典理解相同的答案: d1[key] : value for key, value in d.items()
如果您只想更改某些键,这将中断。使用 if/else 更改部分/全部。(d1[k] if k in d1 else k):v for (k,v) in d.items()
【参考方案3】:
pop'n'fresh
>>>a = 1:2, 3:4
>>>a[5] = a.pop(1)
>>>a
3: 4, 5: 2
>>>
【讨论】:
【参考方案4】:在 python 2.7 及更高版本中,您可以使用字典理解: 这是我在使用 DictReader 读取 CSV 时遇到的示例。用户已在所有列名后加上':'
ori_dict = 'key1:' : 1, 'key2:' : 2, 'key3:' : 3
去除键中的尾随':':
corrected_dict = k.replace(':', ''): v for k, v in ori_dict.items()
【讨论】:
"AttributeError: 'dict' 对象没有属性 'replace'" user1318125,我建议尝试复制粘贴。这在 python 控制台中对我有用(.replace 正在用作键的字符串上执行)【参考方案5】:由于键是字典用来查找值的工具,因此您无法真正更改它们。您可以做的最接近的事情是保存与旧键关联的值,将其删除,然后使用替换键和保存的值添加新条目。其他几个答案说明了实现这一目标的不同方式。
【讨论】:
【参考方案6】:d = 1:2,3:4
假设我们想要更改列表元素 p=['a' , 'b'] 的键。 下面的代码就可以了:
d=dict(zip(p,list(d.values())))
我们得到
'a': 2, 'b': 4
【讨论】:
【参考方案7】:如果你有一个复杂的dict,则表示dict中有一个dict或list:
myDict = 1:"one",2:3:"three",4:"four"
myDict[2][5] = myDict[2].pop(4)
print myDict
Output
1: 'one', 2: 3: 'three', 5: 'four'
【讨论】:
【参考方案8】:没有直接的方法可以做到这一点,但你可以删除然后分配
d = 1:2,3:4
d[newKey] = d[1]
del d[1]
或进行批量键更改:
d = dict((changeKey(k), v) for k, v in d.items())
【讨论】:
d = changeKey(k): v for k, v in d.items()
@Erich 乍一看,d = dict(...)
和 d = ...
是同一个东西。 2013 年的另一条评论建议对另一个答案进行相同的更改。所以我假设它们不能相同,并且它们必须以某种有意义的方式有所不同。那是什么?
@Unknow0059 我的理解是语法糖。这至少是我添加此评论的原因。在实践中,dict()
在传递生成器对象时的行为方式与 ...
的行为方式可能存在差异。对于阅读的一些方向,我想说从这里开始:python.org/dev/peps/pep-0274【参考方案9】:
转换字典中的所有键
假设这是你的字典:
>>> sample = 'person-id': '3', 'person-name': 'Bob'
要将示例字典键中的所有短划线转换为下划线:
>>> sample = key.replace('-', '_'): sample.pop(key) for key in sample.keys()
>>> sample
>>> 'person_id': '3', 'person_name': 'Bob'
【讨论】:
【参考方案10】:这个函数得到一个字典,和另一个指定如何重命名键的字典;它返回一个带有重命名键的新字典:
def rekey(inp_dict, keys_replace):
return keys_replace.get(k, k): v for k, v in inp_dict.items()
测试:
def test_rekey():
assert rekey('a': 1, "b": 2, "c": 3, "b": "beta") == 'a': 1, "beta": 2, "c": 3
【讨论】:
请不要只发布代码作为答案。请解释您的答案/实现。 您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。 这会创建字典的副本。我很失望。就像马蒂诺说的那样。您可以使用print(inp_dict)
而不是assert
进行真实测试。尽管如此,还是比其他选择要好。【参考方案11】:
在一次更改所有键的情况下。 在这里,我正在阻止键。
a = 'making' : 1, 'jumping' : 2, 'climbing' : 1, 'running' : 2
b = ps.stem(w) : a[w] for w in a.keys()
print(b)
>>> 'climb': 1, 'jump': 2, 'make': 1, 'run': 2 #output
【讨论】:
【参考方案12】:这将小写你所有的 dict 键。即使您有嵌套的字典或列表。您可以执行类似的操作来应用其他转换。
def lowercase_keys(obj):
if isinstance(obj, dict):
obj = key.lower(): value for key, value in obj.items()
for key, value in obj.items():
if isinstance(value, list):
for idx, item in enumerate(value):
value[idx] = lowercase_keys(item)
obj[key] = lowercase_keys(value)
return obj
json_str = "FOO": "BAR", "BAR": 123, "EMB_LIST": ["FOO": "bar", "Bar": 123, "FOO": "bar", "Bar": 123], "EMB_DICT": "FOO": "BAR", "BAR": 123, "EMB_LIST": ["FOO": "bar", "Bar": 123, "FOO": "bar", "Bar": 123]
lowercase_keys(json_str)
Out[0]: 'foo': 'BAR',
'bar': 123,
'emb_list': ['foo': 'bar', 'bar': 123, 'foo': 'bar', 'bar': 123],
'emb_dict': 'foo': 'BAR',
'bar': 123,
'emb_list': ['foo': 'bar', 'bar': 123, 'foo': 'bar', 'bar': 123]
【讨论】:
【参考方案13】:用下划线替换dict键中的空格,我用这个简单的路线...
for k in dictionary.copy():
if ' ' in k:
dictionary[ k.replace(' ', '_') ] = dictionary.pop(k, 'e r r')
或者只是 dictionary.pop(k)
注意 'er r' 可以是任何字符串,如果键不在字典中以能够替换它,它将成为新值,这不可能在这里发生。该参数是可选的,在可能遇到 KeyError 的其他类似代码中,添加 arg 可以避免它,但可以使用 'er r' 或您设置的任何值创建一个新键。
.copy() 避免 ... 迭代期间字典大小改变。
.keys() 不需要,k 是每个键,k 代表我头脑中的键。
(我使用的是 v3.7)
Info on dictionary pop()
上面循环的单行代码是什么?
【讨论】:
【参考方案14】:您可以使用 iff/else 字典理解。此方法允许您在一行中替换任意数量的键。
key_map_dict = 'a':'apple','c':'cat'
d = 'a':1,'b':2,'c':3
d = (key_map_dict[k] if k in key_map_dict else k):v for (k,v) in d.items()
返回'apple':1,'b':2,'cat':3
【讨论】:
【参考方案15】:您可以将同一个值与多个键关联,或者只是删除一个键并重新添加一个具有相同值的新键。
例如,如果您有键->值:
red->1
blue->2
green->4
没有理由不能添加purple->2
或删除red->1
并添加orange->1
【讨论】:
【参考方案16】:如果有人想替换多级字典中所有出现的键的方法。
函数检查字典是否有特定的键,然后遍历子字典并递归调用函数:
def update_keys(old_key,new_key,d):
if isinstance(d,dict):
if old_key in d:
d[new_key] = d[old_key]
del d[old_key]
for key in d:
updateKey(old_key,new_key,d[key])
update_keys('old','new',dictionary)
【讨论】:
【参考方案17】:完整解决方案示例
声明一个包含你想要的映射的 json 文件
"old_key_name": "new_key_name",
"old_key_name_2": "new_key_name_2",
加载它
with open("<filepath>") as json_file:
format_dict = json.load(json_file)
创建此函数以使用您的映射格式化字典
def format_output(dict_to_format,format_dict):
for row in dict_to_format:
if row in format_dict.keys() and row != format_dict[row]:
dict_to_format[format_dict[row]] = dict_to_format.pop(row)
return dict_to_format
【讨论】:
【参考方案18】:注意 pop 的位置:将要删除的键放在 pop() 之后orig_dict['AAAAA' ] = orig_dict.pop('A')
orig_dict = 'A': 1, 'B' : 5, 'C' : 10, 'D' : 15
# printing initial
print ("original: ", orig_dict)
# changing keys of dictionary
orig_dict['AAAAA'] = orig_dict.pop('A')
# printing final result
print ("Changed: ", str(orig_dict))
【讨论】:
【参考方案19】:我在下面编写了这个函数,您可以在其中将当前键名的名称更改为新键名。
def change_dictionary_key_name(dict_object, old_name, new_name):
'''
[PARAMETERS]:
dict_object (dict): The object of the dictionary to perform the change
old_name (string): The original name of the key to be changed
new_name (string): The new name of the key
[RETURNS]:
final_obj: The dictionary with the updated key names
Take the dictionary and convert its keys to a list.
Update the list with the new value and then convert the list of the new keys to
a new dictionary
'''
keys_list = list(dict_object.keys())
for i in range(len(keys_list)):
if (keys_list[i] == old_name):
keys_list[i] = new_name
final_obj = dict(zip(keys_list, list(dict_object.values())))
return final_obj
假设一个 JSON,您可以调用它并通过以下行重命名它:
data = json.load(json_file)
for item in data:
item = change_dictionary_key_name(item, old_key_name, new_key_name)
已在此处找到从列表键到字典键的转换:https://www.geeksforgeeks.org/python-ways-to-change-keys-in-dictionary/
【讨论】:
【参考方案20】:使用pandas,您可以拥有这样的东西,
from pandas import DataFrame
df = DataFrame(["fruit":"apple", "colour":"red"])
df.rename(columns = 'fruit':'fruit_name', inplace = True)
df.to_dict('records')[0]
>>> 'fruit_name': 'apple', 'colour': 'red'
【讨论】:
【参考方案21】:我还没有看到这个确切的答案:
dict['key'] = value
您甚至可以对对象属性执行此操作。 通过这样做将它们变成字典:
dict = vars(obj)
然后您可以像操作字典一样操作对象属性:
dict['attribute'] = value
【讨论】:
我没有看到这与问题有什么关系;你能详细说明一下吗?以上是关于更改字典中键的名称的主要内容,如果未能解决你的问题,请参考以下文章