686 Stimmen

Umbenennen eines Wörterbuchschlüssels

Gibt es eine Möglichkeit, einen Wörterbuchschlüssel umzubenennen, ohne seinen Wert einem neuen Namen zuzuweisen und den alten Schlüsselnamen zu entfernen, und ohne durch den Schlüssel/Wert im Wörterbuch zu iterieren?

Falls es sich um OrderedDict handelt, können Sie dasselbe tun, während Sie die Position dieses Schlüssels beibehalten.

1voto

Lokesh Sanapalli Punkte 976

Ich habe diese Funktion entwickelt, die das ursprüngliche Wörterbuch nicht verändert. Diese Funktion unterstützt auch eine Liste von Wörterbüchern.

import functools
from typing import Union, Dict, List

def rename_dict_keys(
    data: Union[Dict, List[Dict]], old_key: str, new_key: str
):
    """
    Diese Funktion benennt die Schlüssel im Wörterbuch um

    :param data:
    :param old_key:
    :param new_key:
    :return: Union[Dict, List[Dict]]
    """
    if isinstance(data, dict):
        res = {k: v for k, v in data.items() if k != old_key}
        try:
            res[new_key] = data[old_key]
        except KeyError:
            raise KeyError(
                "kann den Schlüssel nicht umbenennen, da der alte Schlüssel '%s' nicht im Daten vorhanden ist"
                % old_key
            )
        return res
    elif isinstance(data, list):
        return list(
            map(
                functools.partial(
                    rename_dict_keys, old_key=old_key, new_key=new_key
                ),
                data,
            )
        )
    raise ValueError("erwarteter Typ List[Dict] oder Dict, erhielt '%s' für Daten" % type(data))

0voto

skullgoblet1089 Punkte 554

@helloswift123 Ich mag deine Funktion. Hier ist eine Änderung, um mehrere Schlüssel in einem einzigen Aufruf umzubenennen:

def rename(d, keymap):
    """
    :param d: alter dictionary
    :type d: dict
    :param keymap: [{:Schlüssel von-Schlüssel :Werte zu-Schlüssel} keymap]
    :returns: neues dictionary
    :rtype: dict
    """
    new_dict = {}
    for key, value in zip(d.keys(), d.values()):
        new_key = keymap.get(key, key)
        new_dict[new_key] = d[key]
    return new_dict

0voto

henrry Punkte 384

Sie können den folgenden Code verwenden:

OldDict={'a':'v1', 'b':'v2', 'c':'v3'}

OldKey=['a','b','c']
NewKey=['A','B','C']

def DictKeyChanger(dict,OldKey,NewKey):
    ListAllKey=list(dict.keys())
    for x in range(0,len(NewKey)):
        dict[NewKey[x]]=dict[OldKey[x]] if OldKey[x] in ListAllKey else None
    for x in ListAllKey:
        dict.pop(x)
    return dict

NewDict=DictKeyChanger(OldDict,OldKey,NewKey)
print(NewDict)#===>>{'A': 'v1', 'B': 'v2', 'C': 'v3'}

Notizen:

  1. Die Länge der Liste OldKey und der Liste NewKey muss gleich sein.
  2. Die Länge der Liste OldKey muss gleich der Liste NewKey sein, wenn der Schlüssel nicht im OldKey existiert, setzen Sie stattdessen 'noexis' wie gezeigt.

Beispiel:

OldDict={'a':'v1', 'b':'v2', 'c':'v3'}
OldKey=['a','b','c','noexis','noexis']
NewKey=['A','B','C','D','E']
NewDict=DictKeyChanger(OldDict,OldKey,NewKey)
print(NewDict)#===>>{'A': 'v1', 'B': 'v2', 'C': 'v3', 'D': None, 'E': None}

0voto

Chase Punkte 321

In meinem Fall hatte ich einen Funktionsaufruf, der ein Dictionary zurückgibt, das einen Schlüssel hatte, den ich in einer einzigen Zeile umbenennen wollte, sodass keines dieser Beispiele für mich funktionierte. Ab Python 3.8 können Sie den Walross-Operator verwenden, um es auf eine Zeile zu reduzieren, wenn Sie keine inplace-Operation suchen und das Dictionary noch nicht definiert ist.

old_dict = get_dict()  
# old_dict = {'a': 1, 'b': 2, 'c': 3}

new_dict = {'new1': (x := get_dict()).pop('b'), **x}  
# new_dict = {'a': 1, 'new1': 2, 'c': 3}

-3voto

burhan rashid Punkte 434

Ich habe einige Antworten kombiniert aus dem obigen Thread und habe die Lösung unten entwickelt. Obwohl es einfach ist, kann es als Grundlage für komplexere Schlüsselaktualisierungen aus einem Wörterbuch verwendet werden.

test_dict = {'a': 1, 'b': 2, 'c': 3}
print(test_dict)
# {'a': 1, 'b': 2, 'c': 3}
präfix = 'up'
def dict_key_update(json_file):    
    neue_keys = []
    alte_keys = []
    for i,(key,value) in enumerate(json_file.items()):
        alte_keys.append(key)
        neue_keys.append(str(präfix) + key) # ich habe aktualisiert, indem ich dem Schlüssel ein Präfix hinzufüge
    for alte_key, neue_key in zip(alte_keys,neue_keys):
        print('alt {}, neu {}'.format(alte_key, neue_key))
        if neue_key!=alte_key:  
           json_file[neue_key] = json_file.pop(alte_key)
     return json_file

test_dict = dict_key_update(test_dict)
print(test_dict)
# {'upa': 1, 'upb': 2, 'upc': 3}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X