J'ai un dictionnaire où je veux renommer certaines des touches du dictionnaire qui sont minuscules en casse chameau, mais je veux maintenir la séquence. Y a-t-il un moyen de maintenir l'intégrité?
J'écris un nettoyant qui aidera avec le même et il ressemble à ceci
{
'ID': 5,
'firstName': 'Bob',
'lastName': 'Woolmer',
'gender': 'Male',
'country': 'USA',
'emailId': 'abs@gmail.com'
}
Disons que mon dictionnaire ressemble à ceci
{
'gender': 'Male',
'country': 'USA',
'ID': 5,
'firstName': 'Bob',
'lastName': 'Woolmer',
'emailId': 'abs@gmail.com'
}
J'obtiens le résultat suivant:
person_data = {
'id': 5,
'firstname': 'Bob',
'lastname': 'Woolmer',
'gender': 'Male',
'country': 'USA'
'emailid': 'abs@gmail.com'
}
Le résultat que je veux est:
def key_cleanser(data):
name_cleanse_dict = {
'id': 'ID',
'emailid': 'emailId',
'firstname': 'firstName',
'middlename': 'middleName',
'lastname': 'lastName',
'addressline1': 'addressLine1',
'addressline2': 'addressLine2',
'addressline3': 'addressLine3',
'postalcode': 'postalCode',
}
if isinstance(data, dict):
dictionary = data.copy()
dict_keys = list(dictionary.keys())
for key in dict_keys:
if key in name_cleanse_dict.keys():
dictionary[name_cleanse_dict[key]] = dictionary.pop(key)
key = name_cleanse_dict[key]
return dictionary
return data
Existe-t-il un moyen de maintenir une séquence au cas où je répliquerais cela pour un dictionnaire dynamique.
3 Réponses :
Enregistrez les clés d'origine:
d = {k: d[k] for k in order}
Modifiez les clés. Reconstruisez le dictionnaire dans l'ordre d'origine:
order = d.keys()
Cette solution ne fonctionne que pour Python 3.6+.
Vous pouvez utiliser une méthode de compréhension de dict et de dictionnaire get avec une valeur par défaut.
{name_cleanse_dict.get(key,key):value for (key,value) in person_data.items()}
L'ordre est garanti avec Python3.6 +, sinon vous devriez utilisez OrderedDict
Si vous pouvez remplacer les dictionnaires d'origine par OrderedDicts, quelque chose comme ceci fonctionnerait:
OrderedDict([('id', 5), ('firstname', 'Bob'), ('lastname', 'Woolmer'), ('gender', 'Male'), ('country', 'USA'), ('emailid', 'abs@gmail.com')])
OrderedDict([('ID', 5), ('firstName', 'Bob'), ('lastName', 'Woolmer'), ('gender', 'Male'), ('country', 'USA'), ('emailId', 'abs@gmail.com')])
Sortie:
from collections import OrderedDict
def clense_data(data):
name_cleanse_dict = {
'id': 'ID',
'emailid': 'emailId',
'firstname': 'firstName',
'middlename': 'middleName',
'lastname': 'lastName',
'addressline1': 'addressLine1',
'addressline2': 'addressLine2',
'addressline3': 'addressLine3',
'postalcode': 'postalCode',
}
if isinstance(data, dict):
return OrderedDict([(name_cleanse_dict[k], v) if k in name_cleanse_dict else (k, v) for k, v in data.items()])
return data
def main():
person_data = OrderedDict([('id', 5),
('firstname', 'Bob'),
('lastname', 'Woolmer'),
('gender', 'Male'),
('country', 'USA'),
('emailid', 'abs@gmail.com')])
print(person_data)
new_person_data = clense_data(person_data)
print(new_person_data)
if __name__ == '__main__':
main()
Copie possible de Comment puis-je trier un dictionnaire par clé?
Les dictionnaires Python ne sont, en général, pas classés car les valeurs sont accessibles par des clés et non par des index. Pourquoi voudriez-vous maintenir les positions?
Je ne veux pas trier un dictionnaire par clé. Je souhaite conserver l'ordre des clés même si la première clé commence par un «Z»
dans le dictionnaire python 3.6+ conserve l'ordre d'insertion
@ArpitAcharya Vérifiez la réponse acceptée, vous ne pouvez pas maintenir l'ordre dans un dictionnaire, si vous voulez maintenir l'ordre, vous pouvez utiliser un
OrderedDict.@DYZ: C'est ainsi que les réponses sont évanouies en tant que jsons et sont utilisées par les analystes qui veulent que les identifiants soient en haut suivis du nom. Rien de programmatique mais plus pour les utilisateurs métier et les testeurs au cas où nous aurions affaire à des dictionnaires d'une centaine de clés
Pour la plupart des versions publiées de Python, il n'y a pas du tout de "position" pour les entrées de dictionnaire. Les dictionnaires ne stockent pas les positions; les positions ne sont qu'un artefact accidentel / coïncident de l'ordre de hachage des clés, et comme le hachage est un dérivé indirect de la clé elle-même, il n'y a pas de contrôle de haut niveau de celle-ci (et les tentatives de forcer ce contrôle rendraient potentiellement le stockage beaucoup moins efficace).
3.6 stocke la position et paie un coût supplémentaire d'utilisation de la mémoire pour ce faire, mais il paie ce coût grâce aux grandes améliorations apportées à l'efficacité du dictionnaire par rapport aux anciennes versions, c'est pourquoi il ne paraître plus lent ou plus gourmand en mémoire que les anciennes versions. D'un autre côté, il est plus lent et plus gourmand en RAM qu'un Python 3.6 d'un autre univers qui avait les mêmes optimisations mais n'a pas décidé de consacrer une partie de ses gains à de nouvelles fonctionnalités.
@CharlesDuffy Je n'en serais pas si sûr. L'ordre d'insertion est un effet secondaire des nouvelles optimisations de mémoire dans Python 3.6. Il garde un tableau supplémentaire, mais grâce à cela, le hastable peut gaspiller jusqu'à 24 fois moins de mémoire sur l'espace tampon.
@Charles Duffy: Ce fil indique que CPython améliore en fait l'utilisation de la mémoire en choisissant une implémentation qui maintient l'ordre d'insertion stackoverflow.com/questions/39980323/...
@ArpitAcharya Si vous n'utilisez pas python-3.6 ou plus récent, même sans rien faire sur les clés, si vous lisez simplement un dictionnaire à partir d'une entrée JSON en utilisant le package
json, l'ordre ne serait pas le même . Dans ce cas, la balise doit être remplacée parpython-3.6.