convert - ¿Por qué algunos códigos son deterministas en Python2 y no deterministas en Python 3?
python 2 to python 3 (1)
Si por "no determinista" te refieres al orden en que aparecen las claves del diccionario (cuando recorres un diccionario) los cambios de ejecución a ejecución, y las claves del diccionario son cadenas, por favor dilo. Entonces puedo ayudar. Pero hasta ahora no has dicho nada de eso ;-)
Suponiendo que ese es el problema, aquí hay un pequeño programa:
d = dict((L, i) for i, L in enumerate(''abcd''))
print(d)
y la salida de 4 se ejecuta bajo 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}
La causa se insinúa en esta parte de la salida de 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.
Esta es una "solución de seguridad" a medias, destinada a ayudar a prevenir ataques de DOS basados en la construcción de entradas dict diseñadas para provocar un comportamiento de tiempo cuadrático. "aleatorio" es el predeterminado en Python3.
Puede desactivarlo configurando envar PYTHONHASHSEED en un entero (su elección - elija 0 si no le importa). Luego, la iteración de un dict con claves de cadena las producirá en el mismo orden en las ejecuciones.
Como @AlcariTheMad dijo en un comentario, puede habilitar el comportamiento predeterminado de Python3 en Python 2 a través de python -R ...
Estoy tratando de escribir un script para calcular todas las posibles coincidencias de cadenas difusas para una cadena corta, o ''kmer'', y el mismo código que funciona en Python 2.7.X me da una respuesta no determinista con Python 3.3 .X, y no puedo entender por qué.
Repaso un diccionario, itertools.product, e itertools.combinaciones en mi código, pero los repito en todos hasta completarlos sin interrupciones o continuos. Además, almaceno todos mis resultados en un diccionario separado en lugar del que estoy iterando. En resumen, no estoy cometiendo ningún error que sea obvio para mí, ¿por qué el comportamiento es diferente entre Python2 y Python3?
Muestra, código ligeramente simplificado a continuación:
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