Is there a 'multimap' implementation in Python?

后端 未结 8 1626
离开以前
离开以前 2020-12-01 01:26

I am new to Python, and I am familiar with implementations of Multimaps in other languages. Does Python have such a data structure built-in, or available in a commonly-used

相关标签:
8条回答
  • 2020-12-01 01:33

    There is no multi-map in the Python standard libs currently.

    WebOb has a MultiDict class used to represent HTML form values, and it is used by a few Python Web frameworks, so the implementation is battle tested.

    Werkzeug also has a MultiDict class, and for the same reason.

    0 讨论(0)
  • 2020-12-01 01:47

    You can take list of tuples and than can sort them as if it was a multimap.

    listAsMultimap=[]
    

    Let's append some elements (tuples):

    listAsMultimap.append((1,'a'))
    listAsMultimap.append((2,'c'))
    listAsMultimap.append((3,'d'))
    listAsMultimap.append((2,'b'))
    listAsMultimap.append((5,'e'))
    listAsMultimap.append((4,'d'))
    

    Now sort it.

    listAsMultimap=sorted(listAsMultimap)
    

    After printing it you will get:

    [(1, 'a'), (2, 'b'), (2, 'c'), (3, 'd'), (4, 'd'), (5, 'e')]
    

    That means it is working as a Multimap!

    Please note that like multimap here values are also sorted in ascending order if the keys are the same (for key=2, 'b' comes before 'c' although we didn't append them in this order.)

    If you want to get them in descending order just change the sorted() function like this:

    listAsMultimap=sorted(listAsMultimap,reverse=True)
    

    And after you will get output like this:

    [(5, 'e'), (4, 'd'), (3, 'd'), (2, 'c'), (2, 'b'), (1, 'a')]
    

    Similarly here values are in descending order if the keys are the same.

    0 讨论(0)
  • 2020-12-01 01:47

    The standard way to write this in Python is with a dict whose elements are each a list or set. As stephan202 says, you can somewhat automate this with a defaultdict, but you don't have to.

    In other words I would translate your code to

    a = dict()
    a[1] = ['a', 'b']
    a[2] = ['c']
    
    print(a[1])  # prints: ['a', 'b']
    print(a[2])  # prints: ['c']
    
    0 讨论(0)
  • 2020-12-01 01:50

    Such a thing is not present in the standard library. You can use a defaultdict though:

    >>> 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']
    

    (Instead of list you may want to use set, in which case you'd call .add instead of .append.)


    As an aside: look at these two lines you wrote:

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

    This seems to indicate that you want the expression a[1] to be equal to two distinct values. This is not possible with dictionaries because their keys are unique and each of them is associated with a single value. What you can do, however, is extract all values inside the list associated with a given key, one by one. You can use iter followed by successive calls to next for that. Or you can just use two loops:

    >>> 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'
    
    0 讨论(0)
  • 2020-12-01 01:53

    Just for future visitors. Currently there is a python implementation of Multimap. It's available via pypi

    0 讨论(0)
  • 2020-12-01 01:54

    Stephan202 has the right answer, use defaultdict. But if you want something with the interface of C++ STL multimap and much worse performance, you can do this:

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

    Now when you iterate through multimap, you'll get pairs like you would in a std::multimap. Unfortunately, that means your loop code will start to look as ugly as 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
    

    In summary, defaultdict is really cool and leverages the power of python and you should use it.

    0 讨论(0)
提交回复
热议问题