我正在尝试编写一个脚本来计算所有可能的短字符串或'kmer'的模糊字符串匹配,并且在Python 2.7.X中可以使用相同的代码给我提供了Python 3.3的不确定性答案.X,我不知道为什么。

我在代码中遍历了字典,itertools.product和itertools.combinations,但对所有这些进行了遍历,没有间断或继续。另外,我将所有结果存储在单独的字典中,而不是要迭代的字典中。简而言之-我没有犯任何明显的错误,所以为什么Python2和Python3的行为不同?

示例,下面略有简化的代码:

import itertools

def find_best_fuzzy_kmer( kmers ):
    for kmer, value in kmers.items():
        for similar_kmer in permute_string( kmer, m ):
            # Tabulate Kmer

def permute_string( query, m ):
    query_list = list(query)
    output = set() # hold output
    for i in range(m+1):
        # pre-calculate the possible combinations of new bases
        base_combinations = list(itertools.product('AGCT', repeat=i))
        # for each combination `idx` in idxs, replace str[idx]
        for positions in itertools.combinations(range(len(query_list)), i):
            for bases in base_combinations:
                # Generate Permutations and add to output
    return output

最佳答案

如果用“非确定性”表示,则是指字典键的出现顺序(当您遍历字典时)会随着运行而变化,并且字典键是字符串,请这样说。那我可以帮忙。但是到目前为止,您还没有说过任何一个;-)

假设是问题所在,这是一个小程序:

d = dict((L, i) for i, L in enumerate('abcd'))
print(d)

并且4的输出在Python 3.3.2下运行:
{'d': 3, 'a': 0, 'c': 2, 'b': 1}
{'d': 3, 'b': 1, 'c': 2, 'a': 0}
{'d': 3, 'a': 0, 'b': 1, 'c': 2}
{'a': 0, 'b': 1, 'c': 2, 'd': 3}

原因来自python -h输出的这一部分:
Other environment variables:
...
PYTHONHASHSEED: if this variable is set to 'random', a random value is used
   to seed the hashes of str, bytes and datetime objects.  It can also be
   set to an integer in the range [0,4294967295] to get hash values with a
   predictable seed.

这是一个半熟的“安全修复程序”,旨在基于构造旨在引起二次时间行为的dict输入来帮助防止DOS攻击。 “随机”是Python3中的默认设置。

您可以通过将envar PYTHONHASHSEED设置为整数来关闭它(您的选择-如果您不在乎,则选择0)。然后,使用字符串键迭代字典将在运行中以相同的顺序生成它们。

正如@AlcariTheMad在评论中所说,您可以通过python -R ...在Python 2下启用Python3默认行为。

关于python - 为什么某些代码在Python2中是确定性的,而在Python 3中却是不确定性的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19872253/

10-12 21:42