我是新来的Python,和我熟悉的实现屈德宁在其他 语言。Python是否内置了这样的数据结构,或者在常用的库中可用?
为了说明我所说的“ multimap”:
a = multidict()
a[1] = 'a'
a[1] = 'b'
a[2] = 'c'
print(a[1]) # prints: ['a', 'b']
print(a[2]) # prints: ['c']
a[1] = 'b'
意思会使人们阅读或维护此代码感到困惑。我建议您不要在Python中执行此操作。
Answers:
这样的事情在标准库中不存在。您可以使用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有python实现。可以通过pypi获得
defaultdict(set)
有何不同?
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
它确实很酷并且可以利用python的功能,因此您应该使用它。
您可以获取元组列表,然后可以像对待多图一样对其进行排序。
listAsMultimap=[]
让我们附加一些元素(元组):
listAsMultimap.append((1,'a'))
listAsMultimap.append((2,'c'))
listAsMultimap.append((3,'d'))
listAsMultimap.append((2,'b'))
listAsMultimap.append((5,'e'))
listAsMultimap.append((4,'d'))
现在排序。
listAsMultimap=sorted(listAsMultimap)
打印后,您将获得:
[(1, 'a'), (2, 'b'), (2, 'c'), (3, 'd'), (4, 'd'), (5, 'e')]
这意味着它正在作为多图工作!
请注意,如果键相同,则此处的值与multimap一样也按升序排序(对于key = 2,尽管我们未按此顺序附加键,但键b在'c'之前)。
如果要按降序获取它们,只需更改sorted()函数,如下所示:
listAsMultimap=sorted(listAsMultimap,reverse=True)
然后,您将获得如下输出:
[(5, 'e'), (4, 'd'), (3, 'd'), (2, 'c'), (2, 'b'), (1, 'a')]
同样,如果键相同,则值按降序排列。
用Python编写此代码的标准方法是使用一个dict,其元素分别为a list
或set
。正如stephan202所说,您可以使用defaultdict在某种程度上自动执行此操作,但不必这样做。
换句话说,我会将您的代码翻译成
a = dict()
a[1] = ['a', 'b']
a[2] = ['c']
print(a[1]) # prints: ['a', 'b']
print(a[2]) # prints: ['c']
a[1] = 'b'
视为“附加”而不是“替换”,a[1]
比提供帮助更令人困惑。
或子类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)