Python 替代使用列表作为字典键?
Python alternative to using List as Dictionary Key?
我目前有一个字典,可以将标准化的互信息分数映射到多序列比对中的比对位点,这些位点存储在一个列表中。但是,我意识到两个列表可能恰好具有相同的分数。因此,只有一个列表将存储在字典中,因为分数是关键。虽然集群应该是唯一的,但我不确定该怎么做,因为我的列表没有哈希函数。
这是我的数据的样子。理想情况下,我只想反转键和值。
{
0.475: [10, 11]
0.434: [12, 14]
0.404: [16, 18]
0.341: [21, 22]
}
你可以在这里使用字典的理解:
d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}
print({tuple(d[n]):n for n in d})
输出
{(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}
您不能直接反转键和值,因为列表是不可散列的,因此不能保留为键。
更新
如果您有重复的列表,您可能希望创建重复列表的枚举。你可以这样做:
from collections import defaultdict
d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [12, 14]}
new_d = dict()
d_counts = defaultdict(int)
for n in d.keys():
value = tuple(d[n])
new_d[(value, d_counts[value])] = n
d_counts[value] += 1
print(new_d)
输出2
{((10, 11), 0): 0.475, ((12, 14), 0): 0.434, ((16, 18), 0): 0.404, ((12, 14), 1): 0.341}
mydict = {0.475: [10, 11],
0.434: [12, 14],
0.404: [16, 18],
0.341: [21, 22]}
newdict = dict()
for k, v in mydict.items():
newdict[tuple(v)] = k
print(newdict)
# {(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}
从 this answer 开始,您可以尝试从内置 dict
:
创建一个新的 class
class Dictlist(dict):
def __setitem__(self, key, value):
try:
self[key]
except KeyError:
super(Dictlist, self).__setitem__(key, [])
self[key].append(value)
所以...
>>> d = Dictlist()
>>> d['100'] = [1, 2]
>>> d['100'] = [3, 4]
>>> d
{'100': [[1, 2], [3, 4]]}
Dictionary comprehension应该没问题。
my_dict = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}
my_dict = {my_dict[k]:k for k in my_dict}
注意:如果你想在里面有一个if-statement,你可以。
我目前有一个字典,可以将标准化的互信息分数映射到多序列比对中的比对位点,这些位点存储在一个列表中。但是,我意识到两个列表可能恰好具有相同的分数。因此,只有一个列表将存储在字典中,因为分数是关键。虽然集群应该是唯一的,但我不确定该怎么做,因为我的列表没有哈希函数。
这是我的数据的样子。理想情况下,我只想反转键和值。
{
0.475: [10, 11]
0.434: [12, 14]
0.404: [16, 18]
0.341: [21, 22]
}
你可以在这里使用字典的理解:
d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}
print({tuple(d[n]):n for n in d})
输出
{(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}
您不能直接反转键和值,因为列表是不可散列的,因此不能保留为键。
更新
如果您有重复的列表,您可能希望创建重复列表的枚举。你可以这样做:
from collections import defaultdict
d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [12, 14]}
new_d = dict()
d_counts = defaultdict(int)
for n in d.keys():
value = tuple(d[n])
new_d[(value, d_counts[value])] = n
d_counts[value] += 1
print(new_d)
输出2
{((10, 11), 0): 0.475, ((12, 14), 0): 0.434, ((16, 18), 0): 0.404, ((12, 14), 1): 0.341}
mydict = {0.475: [10, 11],
0.434: [12, 14],
0.404: [16, 18],
0.341: [21, 22]}
newdict = dict()
for k, v in mydict.items():
newdict[tuple(v)] = k
print(newdict)
# {(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}
从 this answer 开始,您可以尝试从内置 dict
:
class Dictlist(dict):
def __setitem__(self, key, value):
try:
self[key]
except KeyError:
super(Dictlist, self).__setitem__(key, [])
self[key].append(value)
所以...
>>> d = Dictlist()
>>> d['100'] = [1, 2]
>>> d['100'] = [3, 4]
>>> d
{'100': [[1, 2], [3, 4]]}
Dictionary comprehension应该没问题。
my_dict = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}
my_dict = {my_dict[k]:k for k in my_dict}
注意:如果你想在里面有一个if-statement,你可以。