Nice programing

파이썬에 '멀티 맵'구현이 있습니까?

nicepro 2020. 11. 17. 21:05
반응형

파이썬에 '멀티 맵'구현이 있습니까?


파이썬에 새로운 오전, 나는 구현 익숙 multimap의 에서 다른 언어 . 파이썬에는 그러한 데이터 구조가 내장되어 있습니까, 아니면 일반적으로 사용되는 라이브러리에서 사용할 수 있습니까?

"멀티 맵"이 의미하는 바를 설명하려면 :

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

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

그런 것은 표준 라이브러리에 없습니다. defaultdict그래도 사용할 수 있습니다 .

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

(대신 list을 사용하고 싶을 수 있으며 set,이 경우 .add대신을 호출 합니다 .append.)


제쳐두고 : 당신이 작성한 다음 두 줄을보십시오.

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

이것은 표현식 a[1]이 두 개의 고유 값과 같기를 원한다는 것을 나타냅니다 . 사전에서는 키가 고유하고 각 키가 단일 값과 연결되어 있으므로 사전에서는 불가능합니다. 그러나 있는 것은 주어진 키와 관련된 목록 내의 모든 값을 하나씩 추출하는 것입니다. 당신은 iter그것을 next위해 연속적인 호출을 사용할 수 있습니다 . 또는 두 개의 루프를 사용할 수 있습니다.

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

미래의 방문객을 위해. 현재 Multimap의 파이썬 구현이 있습니다. pypi 를 통해 사용할 수 있습니다.


Stephan202의 정답이 있습니다 defaultdict.. 그러나 C ++ STL 멀티 맵의 인터페이스와 훨씬 더 나쁜 성능을 원하는 경우 다음을 수행 할 수 있습니다.

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

당신을 통해 반복 할 때 이제 multimap당신은에서와 같이, 당신은 쌍을 얻을 것이다 std::multimap. 불행히도, 그것은 당신의 루프 코드가 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

요약하면, defaultdict정말 멋지고 파이썬의 힘을 활용하므로 사용해야합니다.


파이썬에서 이것을 작성하는 표준 방법은 요소가 각각 a list또는 인 dict를 사용하는 것 set입니다. 으로 stephan202는 말한다 , 당신은 다소 defaultdict 이것을 자동화 할 수 있습니다,하지만 당신은 필요가 없습니다.

즉, 귀하의 코드를

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

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

또는 하위 클래스 dict:

class Multimap(dict):
    def __setitem__(self, key, value):
        if key not in self:
            dict.__setitem__(self, key, [value])  # call super method to avoid recursion
        else
            self[key].append(value)

현재 Python 표준 라이브러리에는 멀티 맵이 없습니다.

WebOb에는 HTML 양식 값을 나타내는 데 사용되는 MultiDict 클래스가 있으며 일부 Python 웹 프레임 워크에서 사용되므로 구현이 전투 테스트를 거쳤습니다.

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


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.


I do not clearly understand the semantics of your example

a[1] = 'a'
a[1] = 'b' #??

Is second line a[1] = 'b' supposed to replace the element at [1]. If yes, then you need to use dictionary. If not - you need to use dictionary of lists (as already suggested)

참고URL : https://stackoverflow.com/questions/1731971/is-there-a-multimap-implementation-in-python

반응형