每个值多个键

是否可以在Python字典中为每个值分配多个键。 一个可能的解决scheme是为每个键分配值:

dict = {'k1':'v1', 'k2':'v1', 'k3':'v1', 'k4':'v2'} 

但是由于我的数据文件大于2 GB,这不是有效的内存。 否则,你可以做一个字典键的字典:

 key_dic = {'k1':'k1', 'k2':'k1', 'k3':'k1', 'k4':'k4'} dict = {'k1':'v1', 'k4':'v2'} main_key = key_dict['k2'] value = dict[main_key] 

这也是非常耗费时间和精力的,因为我必须经历整个字典/文件两次。 有没有其他简单和内置的Python解决scheme?

注意:我的字典值不是简单的string(如在问题“v1”,“v2”)相当复杂的对象(包含不同的其他字典/列表等,不可能腌他们)

注意:问题似乎相似, 我怎样才能使用一个键和一个索引相同的字典值? 但我不是在寻找有序/索引的字典,我正在寻找其他有效的解决scheme(如果有的话),除了这个问题中提到的两个。

什么types的价值?

 dict = {'k1':MyClass(1), 'k2':MyClass(1)} 

会给重复的值对象,但是

 v1 = MyClass(1) dict = {'k1':v1, 'k2':v1} 

导致两个键都引用相同的实际对象。

在原来的问题中,你的值是string:即使你声明了两次相同的string,我认为他们会在这种情况下被实现为同一个对象


NB。 如果你不确定你是否已经结束重复,你可以这样找出来:

 if dict['k1'] is dict['k2']: print("good: k1 and k2 refer to the same instance") else: print("bad: k1 and k2 refer to different instances") 

is检查感谢JFSebastian,取代id()

看看这个 – 这是你正在问什么的实现:multi_key_dict(离子)

https://pypi.python.org/pypi/multi_key_dict (来源https://github.com/formiaczek/python_data_structures/tree/master/multi_key_dict

(在Unix平台上,它可能是一个包,你可以尝试使用类似的东西来安装它:

 sudo apt-get install python-multi-key-dict 

对于Debian或者你的发行版的等价物)

您可以使用不同types的键,但也可以使用相同types的键。 您也可以使用您select的键types来迭代项目,例如:

 m = multi_key_dict() m['aa', 12] = 12 m['bb', 1] = 'cc and 1' m['cc', 13] = 'something else' print m['aa'] # will print '12' print m[12] # will also print '12' # but also: for key, value in m.iteritems(int): print key, ':', value # will print:1 # 1 : cc and 1 # 12 : 12 # 13 : something else # and iterating by string keys: for key, value in m.iteritems(str): print key, ':', value # will print: # aa : 12 # cc : something else # bb : cc and 1 m[12] = 20 # now update the value print m[12] # will print '20' (updated value) print m['aa'] # will also print '20' (it maps to the same element) 

密钥的数量没有限制,所以代码如下:

 m['a', 3, 5, 'bb', 33] = 'something' 

是有效的,并且可以使用任何一个键来引用如此创build的值(要么读/写,要么删除它)。

编辑:从2.0版本,它也应该与python3。

我很惊讶没有人提到用字典来使用元组。 这工作得很好:

 my_dictionary = {} my_dictionary[('k1', 'k2', 'k3')] = 'v1' my_dictionary[('k4')] = 'v2' 

使用Python 2.7 / 3,你可以将一个元组,值对与字典理解结合起来。

 keys_values = ( (('k1','k2'), 0), (('k3','k4','k5'), 1) ) d = { key : value for keys, value in keys_values for key in keys } 

您也可以同样更新字典。

 keys_values = ( (('k1',), int), (('k3','k4','k6'), int) ) d.update({ key : value for keys, value in keys_values for key in keys }) 

我不认为这真的是你的问题的核心,但根据标题,我认为这属于这里。

您可以构build已经从parsing的数据创build的对象的辅助字典。 关键是parsing的数据,值将是你的构造对象 – 比如string值应该被转换为某个特定的对象。 这样你可以控制何时构build新的对象:

 existing = {} # auxiliary dictionary for making the duplicates shared result = {} for k, v in parsed_data_generator(): obj = existing.setdefault(v, MyClass(v)) # could be made more efficient result[k] = obj 

然后,所有result字典重复值对象将由MyClass类的单个对象表示。 在build立结果之后,可以删除existing辅助词典。

这里dict.setdefault()可能是优雅和简短的。 但是,您应该稍后再testing更健谈的解决scheme是不是更有效率 – 见下文。 原因是MyClass(v)总是被创build(在上面的例子中),如果它的重复存在,则抛出:

 existing = {} # auxiliary dictionary for making the duplicates shared result = {} for k, v in parsed_data_generator(): if v in existing: obj = existing[v] else: obj = MyClass(v) existing[v] = obj result[k] = obj 

v没有被转换成任何特殊的时候,这个技巧也可以被使用。 例如,如果v是一个string,则辅助字典中的键和值将具有相同的值。 但是,字典的存在确保了对象将被共享(这并不总是由Python来保证)。

我能够实现使用pandasMultiIndex类似的function,虽然在我的情况下,值是标量:

 >>> import numpy >>> import pandas >>> keys = [numpy.array(['a', 'b', 'c']), numpy.array([1, 2, 3])] >>> df = pandas.DataFrame(['val1', 'val2', 'val3'], index=keys) >>> df.index.names = ['str', 'int'] >>> df.xs('b', axis=0, level='str') 0 int 2 val2 >>> df.xs(3, axis=0, level='int') 0 str c val3