Python 如何使用排列生成字典的键

Python 如何使用排列生成字典的键,python,dictionary,permutation,Python,Dictionary,Permutation,我需要创建一个字典,值可以留空或为零,但我需要键是所有可能的ABCD字符与长度k的组合。例如,对于k=8 lex = defaultdict(int) lex = { 'AAAAAAAA':0, 'AAAAAAAB':0, 'AAAAAABB':0, ...} 到目前为止,我已经尝试过这样的想法,我知道这是错误的,但我不知道如何让它工作,我是python新手,所以请容忍我 mydiction = {} mylist = [] mylist = itertools.permutatio

我需要创建一个字典,值可以留空或为零,但我需要键是所有可能的ABCD字符与长度k的组合。例如,对于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)

您可以在一行中完成,但您需要的是带有替换的组合

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

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

但是,请注意,这里有六万个组合。试图将它们全部放在一个目录中,甚至只是对它们进行迭代,都不会产生令人满意的结果


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

尽管带有替换函数的组合工作得非常好,但您将生成一个冲突率相对较高(约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}

您可以在此处使用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
我知道玩这些数字不是最好的做法,我知道有更好的解决方案来解决我试图做的事情,只是让算法更优雅是一项更复杂的任务。这就是为什么我需要用这种“蛮力”方法来完成这一部分,在我得到结果后,我将尝试对其进行细化。这不会生成带替换的组合,而是笛卡尔积。我不确定我是否相信你的冲突率:对我来说,即使有一个20个字符的键,我的字典大小为852610和852529个唯一散列,所以冲突率可以忽略不计。(我认为不管怎么说,担心这个问题是愚蠢的,但我不能理解你的数字来自哪里。)事实上,验证并不难,创建一个这样的字符串列表,创建一个由每个元素的哈希组成的列表,并将其设置为一个集合。集合和列表之间的长度差等于碰撞次数。当然这不是一个问题,众所周知,字符串哈希具有良好的性能。仅使用8个字符长度的字符串找到20%的数字。当然,需要进行更深入的分析,而且我相信对整体性能的影响可能很小,但这仅仅意味着这不是最佳解决方案:)这是由于文字数量少。但这就是我获得上述数字的原因。对于一个8个字符的字符串,我没有得到任何哈希冲突。如果“AAAB”和“BAAA”的碰撞率为20%,是否相等?