Python中是否有“multimap”实现?
我是Python新手,熟悉其他 语言的Multimaps实现。 Python是否具有内置的这种数据结构,或者可以在常用的库中使用?
为了说明我的意思是“多图”:
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'
这似乎表明,您希望expression式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
Stephan202有正确的答案,使用defaultdict
。 但是如果你想用C ++ STL multimap的接口和更糟的性能,你可以这样做:
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的力量,你应该使用它。
或者子类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 Web框架所使用,因此实现是经过战斗testing的。
Werkzeug也有一个MultiDict类,出于同样的原因。
用Python编写这个标准的方法是使用一个字典,其元素是一个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] = 'a' a[1] = 'b' #??
是第二行a[1] = 'b'
应该取代[1]中的元素。 如果是,那么你需要使用字典。 如果没有 – 你需要使用列表字典(如已经build议)