Création de dictionnaires avec des clés prédéfinies
-
03-07-2019 - |
Question
En python, existe-t-il un moyen de créer une classe traitée comme un dictionnaire mais dont les clés sont prédéfinies lors de la création d'une nouvelle instance?
La solution
Vous pouvez facilement étendre n'importe quel type intégré. Voici comment vous le feriez avec un dict:
>>> class MyClass(dict):
... def __init__(self, *args, **kwargs):
... self['mykey'] = 'myvalue'
... self['mykey2'] = 'myvalue2'
...
>>> x = MyClass()
>>> x['mykey']
'myvalue'
>>> x
{'mykey2': 'myvalue2', 'mykey': 'myvalue'}
Je n'ai pas trouvé la documentation Python qui en parle, mais le très populaire livre Dive Into Python (disponible en ligne gratuitement) en donne quelques exemples .
Autres conseils
Vous pouvez également demander à la sous-classe dict de limiter les clés à une liste prédéfinie, en remplaçant __ setitem __ ()
>>> class LimitedDict(dict):
_keys = "a b c".split()
def __init__(self, valtype=int):
for key in LimitedDict._keys:
self[key] = valtype()
def __setitem__(self, key, val):
if key not in LimitedDict._keys:
raise KeyError
dict.__setitem__(self, key, val)
>>> limited = LimitedDict()
>>> limited['a']
0
>>> limited['a'] = 3
>>> limited['a']
3
>>> limited['z'] = 0
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
limited['z'] = 0
File "<pyshell#56>", line 8, in __setitem__
raise KeyError
KeyError
>>> len(limited)
3
Oui, en Python dict
est une classe, vous pouvez donc la sous-classer:
class SubDict(dict):
def __init__(self):
dict.__init__(self)
self.update({
'foo': 'bar',
'baz': 'spam',})
Ici, vous remplacez la méthode __ init __ ()
de dict (une méthode appelée lors de la création d'une instance de la classe). Dans __ init __
, vous appelez d'abord la méthode __ init __ ()
de supercalss, pratique courante lorsque vous souhaitez développer les fonctionnalités de la classe de base. Ensuite, vous mettez à jour la nouvelle instance de SubDictionary
avec vos données initiales.
subDict = SubDict()
print subDict # prints {'foo': 'bar', 'baz': 'spam'}
Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
grep{ Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
l = ["a","a","b","c","c","c"]
d = {}
for item in l:
d[item] += 1
Traceback (most recent call last):
File "./y.py", line 6, in
d[item] += 1
KeyError: 'a'
Python ne vous donnera pas ceci gratuitement:
from collections import defaultdict
from operator import itemgetter
l = ["a","a","b","c","c","c"]
d = defaultdict(int)
for item in l:
d[item] += 1
dl = sorted(d.items(),key=itemgetter(1), reverse=True)
for item in dl:
print item
('c', 3)
('a', 2)
('b', 1)
cependant, defaultdict le fera pour vous,
<*>{ Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>}++} qw/ a a b c c c /;
print map{ Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>."\t". Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>{ Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>}."\n"} sort { Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>{$b} Je ne suis pas sûr que vous recherchiez ce que vous cherchiez, mais lorsque j'ai lu votre message, j'ai tout de suite pensé que vous cherchiez à générer dynamiquement des clés pour compter les exercices.
Contrairement à perl, qui le fera pour vous par défaut,
<*>
Python ne vous donnera pas ceci gratuitement:
<*>
cependant, defaultdict le fera pour vous,
<*>{$a}} keys %_;
c 3
a 2
b 1
Python ne vous donnera pas ceci gratuitement:
<*>cependant, defaultdict le fera pour vous,
<*>Créez simplement une sous-classe de dict et ajoutez les clés dans la méthode init .
class MyClass(dict) def __init__(self): """Creates a new dict with default values"""" self['key1'] = 'value1'
Rappelez-vous cependant qu'en python, toute classe qui "agit comme un dict" est généralement traitée comme telle, de sorte que vous n'avez pas à vous inquiéter trop du fait qu'il s'agisse d'une sous-classe, vous pouvez plutôt implémenter les méthodes dict. L’approche ci-dessus vous est probablement plus utile:).