22

我正在尝试编写一个脚本来计算所有可能的模糊字符串匹配匹配到一个短字符串或“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
4

1 回答 1

35

如果“非确定性”是指字典键出现的顺序(当您迭代字典时)从运行到运行而变化,并且字典键是字符串,请这样说。那我可以帮忙。但是到目前为止,您还没有说过任何话;-)

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

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)。然后使用字符串键迭代 dict 将在运行中以相同的顺序生成它们。

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

于 2013-11-09T04:16:46.893 回答