Deux approches, en fonction de vos entrées:
Option 1: Si, comme dans votre exemple, toutes les clés assorties sont consécutives (vous voyez toujours tous ensemble colours
), vous pouvez utiliser itertools.groupby
les regrouper:
from collections import OrderedDict
from itertools import groupby
from operator import itemgetter
list1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']]
dict1 = OrderedDict((k, [v for _, v in grp]) for k, grp in groupby(list1, itemgetter(0)))
Ceci est, au moins en théorie, l'approche la plus rapide, car il écrit chaque clé dans le dict
exactement une fois sans les regarder à plusieurs reprises chaque fois qu'une touche est vu, mais elle repose sur l'entrée étant commandée par la clé .
Option 2: Utilisez la __missing__
méthode spéciale pour faire un OrderedDict
avec le même comportement sur la recherche une clé manquante comme defaultdict(list)
(malheureusement, les deux types sont incompatibles, de sorte que vous ne pouvez pas faire une classe qui hérite à la fois et appeler un jour), puis écrire une boucle explicite pour le remplir:
from collections import OrderedDict
class OrderedMultidict(OrderedDict):
__slots__ =() # Avoid overhead of per-instance __dict__
def __missing__(self, key):
# Missing keys are seamlessly initialized to an empty list
self[key] = retval = []
return retval
utiliser ensuite pour accumuler les résultats:
dict1 = OrderedMultidict()
for k, v in list1:
dict1[k].append(v)
Cette approche supprime la dépendance de commande de l'option 1, en échange pour ajouter des recherches répétées de chaque clé (bien que seule la première recherche invoque le code de niveau Python dans __missing__
; après cela, si OrderedDict
est au niveau C comme dans le code Python 3 moderne, les recherches resteront également au niveau C). Cela dit, alors que les recherches répétées sont théoriquement un peu moins bonnes que d'écrire chaque clé une seule fois, en pratique, je pense que cette solution sera plus rapide sur CPython moderne (où OrderedDict
est un C intégré); sur Python 2 et plus ancien Python 3, où il est implémenté en Python (alors que groupby
est toujours au niveau C), groupby
est plus susceptible de gagner, mais lorsque les deux types sont accélérés en C, groupby
a en fait un surcoût supplémentaire qui peut le faire perdre.