【问题标题】:How to generate the keys of a dictionary using permutations如何使用排列生成字典的键
【发布时间】:2013-11-15 12:25:08
【问题描述】:

我需要创建一个字典,值可以留空或为零,但我需要键是长度为 k 的 ABCD 字符的所有可能组合。例如,对于 k = 8

lex = defaultdict(int)     
lex = {
'AAAAAAAA':0,
'AAAAAAAB':0,
'AAAAAABB':0,
...}

到目前为止,我已经尝试过这样的想法,我知道这是错误的,但我不知道如何使它工作,我是 python 新手,所以请多多包涵。

mydiction = {}
mylist = []
mylist = itertools.permutations('ACTG', 8)
for keys in mydiction:
    mydiction[keys] = mylist.next()
print(mydiction)

【问题讨论】:

  • 'AAAB' 和 'BAAA' 等效吗?

标签: python dictionary permutation


【解决方案1】:

一行可以搞定,但你要找的是combinations_with_replacement

from itertools import combinations_with_replacement
mydict = {"".join(key):0 for key in combinations_with_replacement('ACTG', 8)}

【讨论】:

  • 你可以在这里使用dict.fromkeys(iterable, 0) 代替dict-comp
  • @JonClements 但是必须加入密钥。 fromKeys 不可能做到这一点,对吧?
  • 报废——在不得不输入一个 gen-exp 之后你什么也得不到...... :)
  • 哇它好用!谢谢你!但结果是: ('G', 'G', 'A', 'C', 'T', 'T', 'C', 'A'): 0, 我可以做些什么修改来制作钥匙更像是字符串而不是列表 ('GGACTTCA'): 0,还有一个问题,为什么在排列参数中添加 *2?
  • @fractal_7 我的错。我们不需要那个* 2
【解决方案2】:

您所描述的不是排列,而是替换的组合。在 itertools 模块中也有一个函数。

但是请注意,那里有六万种组合。试图将它们全部放在一个 dict 中,甚至只是遍历它们,都不会产生令人满意的结果。

您的用例是什么?您可能只需要识别组合,而不是详尽地生成它们。而且每个组合本质上都与一个特定的 16 位整数索引相关联,因此您可以改为存储和操作它。

【讨论】:

  • 我知道玩这样的数字并不是最好的做法,而且我知道我尝试做的事情有更好的解决方案,只是让算法更优雅更复杂任务。这就是为什么我需要用这种“蛮力”方法来完成这部分,在我得到结果后,我会尝试改进它。
【解决方案3】:

虽然combinations_with_replacement 函数工作得非常好,但您将生成一个巨大的字符串列表,其碰撞率相对较高(大约20%)

您想要做的事情可以使用 base4 整数来完成。它们不仅处理速度更快,内存效率更高,而且它们也有 0 冲突(每个数字都是它自己的哈希),这意味着在最坏的情况下有保证的 O(1) 查找时间。

def num_to_hash(n, k, literals='ABCD'):
    return ''.join((literals[(n >> (k - x)*2 & 3)] for x in xrange(1, k+1)))

k = 2
d = {num_to_hash(x, k, 'ACTG'): 0 for x in xrange((4**k) - 1)}
print d 

输出:

{'AA': 0,
 'AC': 0,
 'AG': 0,
 'AT': 0,
 'CA': 0,
 'CC': 0,
 'CG': 0,
 'CT': 0,
 'GA': 0,
 'GC': 0,
 'GT': 0,
 'TA': 0,
 'TC': 0,
 'TG': 0,
 'TT': 0}

【讨论】:

  • 这不会生成带替换的组合,而是生成笛卡尔积。而且我不确定我是否购买了您的冲突率:对我来说,即使使用 20 个字符的密钥,我的字典大小也是 852610 和 852529 个唯一哈希,因此冲突率可以忽略不计。 (我认为无论如何担心它是愚蠢的,但我无法知道你的数字来自哪里。)
  • 实际上不难验证,创建一个这样的字符串列表,创建一个由每个元素的哈希组成的列表,并将其组成一个集合。集合和列表之间的长度差等于冲突的次数。当然这不是问题,众所周知,字符串哈希具有良好的性能。仅使用 8 个字符长度的字符串找到了 20% 的数字。当然需要进行更深入的分析,而且我确信对整体性能的影响可能很小,但这只是意味着它不是最好的解决方案 :) 这是由于文字数量很少。
  • 但这就是我得到上述数字的地方。对于 8 个字符的字符串,我根本没有哈希冲突。如果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多