更改字典中键的名称

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-&gt;2 或删除red-&gt;1 并添加orange-&gt;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

【讨论】:

我没有看到这与问题有什么关系;你能详细说明一下吗?

以上是关于更改字典中键的名称的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python中更改嵌套字典中键的值[关闭]

根据对象中键的名称过滤对象数组[重复]

如何更新嵌套字典中键的值?

swift 3通过字典中键的字符串值过滤字典数组

如何展平Python字典中键的值(元组列表列表)?

在 Python 中使用 None 值删除字典中键的正确方法