83 votes

Existe-t-il une implémentation 'multi-cartes' en Python?

Je suis nouveau sur Python et je suis familier avec les implémentations de Multimaps dans d’ autres langues . Python a-t-il une telle structure de données intégrée ou disponible dans une bibliothèque couramment utilisée?

Pour illustrer ce que je veux dire par "carte multiple":

 a = multidict()
a[1] = 'a'
a[1] = 'b'
a[2] = 'c'

print(a[1])  # prints: ['a', 'b']
print(a[2])  # prints: ['c']
 

138voto

Stephan202 Points 27707

Une telle chose n'est pas présent dans la bibliothèque standard. Vous pouvez utiliser un defaultdict bien que:

>>> from collections import defaultdict
>>> md = defaultdict(list)
>>> md[1].append('a')
>>> md[1].append('b')
>>> md[2].append('c')
>>> md[1]
['a', 'b']
>>> md[2]
['c']

(Au lieu de list vous pouvez utiliser set, auquel cas vous dirais .add au lieu de .append.)


En aparté: regardez ces deux lignes que vous avez écrit:

a[1] = 'a'
a[1] = 'b'

Cela semble indiquer que vous souhaitez que l'expression a[1] être égale à deux valeurs distinctes. Ce n'est pas possible avec les dictionnaires parce que leurs clés sont uniques et chacun d'eux est associé à une valeur unique. Ce que vous pouvez faire, cependant, est d'extraire toutes les valeurs à l'intérieur de la liste associée à une clé donnée, un par un. Vous pouvez utiliser iter , suivie par des appels successifs à l' next pour que. Ou vous pouvez simplement utiliser deux boucles:

>>> for k, v in md.items():
...     for w in v:
...         print("md[%d] = '%s'" % (k, w))
... 
md[1] = 'a'
md[1] = 'b'
md[2] = 'c'

10voto

Michal Points 736

Juste pour les futurs visiteurs. Il existe actuellement une implémentation python de Multimap. Il est disponible via Pypi

4voto

amwinter Points 794

Stephan202 a le droit de répondre, utilisez defaultdict. Mais si vous voulez quelque chose avec l'interface de C++ STL multimap et bien plus de performances, vous pouvez faire ceci:

multimap = []
multimap.append( (3,'a') )
multimap.append( (2,'x') )
multimap.append( (3,'b') )
multimap.sort()

Maintenant, quand vous itérer multimap, vous obtiendrez des paires comme vous le feriez dans un std::multimap. Malheureusement, cela signifie que votre code de boucle va commencer à rechercher aussi laid que C++.

def multimap_iter(multimap,minkey,maxkey=None):
  maxkey = minkey if (maxkey is None) else maxkey
  for k,v in multimap:
    if k<minkey: continue
    if k>maxkey: break
    yield k,v

# this will print 'a','b'
for k,v in multimap_iter(multimap,3,3):
  print v

En résumé, defaultdict est vraiment cool et tire parti de la puissance de python et vous devez l'utiliser.

3voto

poolie Points 3028

La manière standard d'écrire cela en Python est avec un dict dont les éléments sont chacun%%,%% list ou set . Comme stephan202 le dit , vous pouvez automatiser un peu cela avec un defaultdict, mais ce n'est pas obligatoire.

En d'autres termes, je traduirais votre code en

 a = dict()
a[1] = ['a', 'b']
a[2] = ['c']

print(a[1])  # prints: ['a', 'b']
print(a[2])  # prints: ['c']
 

2voto

Luciano Ramalho Points 825

Il n'y a pas de multi-carte dans les bibliothèques standard Python actuellement.

WebOb a une classe MultiDict utilisée pour représenter les valeurs de formulaire HTML. Elle est utilisée par quelques frameworks Web Python. Son implémentation est donc testée au combat.

Werkzeug a également une classe MultiDict et pour la même raison.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X