Tengo la intención de crear miles de pares de enteros, numerarlos y almacenarlos en un diccionario. Dado un número n , mi objetivo es generar cada par (i,j) tal que i<j .
Por ejemplo, si n=4 , los pares serán entonces el diccionario se verá como {(0, 1): 0, (0, 2): 1, (0, 3): 2, (1, 2): 3, (1, 3): 4, (2, 3): 5} .
Puedo generar este diccionario usando bucles for anidados, pero no es eficiente cuando n es grande. ¿Alguien podría ayudarme a realizar esta operación más rápido de lo que lo hago actualmente?
d={} n=4 temp =0 for i in range(n): for j in range(n): if i <j: d.update({(i,j): temp}) temp+= 1Este es un trabajo perfecto para itertools.combinations ya que solo producirá las combinaciones requeridas:
from itertools import combinations n = 4 out = {k:v for v,k in enumerate(combinations(range(n), 2))} salida: {(0, 1): 0, (0, 2): 1, (0, 3): 2, (1, 2): 3, (1, 3): 4, (2, 3): 5}
Tenga en cuenta que podría volver a trabajar su código para producir solo las combinaciones requeridas:
d={} n=4 temp = 0 for j in range(n): for i in range(j): d[(i,j)] = temp temp += 1 # {(0, 1): 0, (0, 2): 1, (1, 2): 2, (0, 3): 3, (1, 3): 4, (2, 3): 5}Dando un paso más allá:
from itertools import combinations, count n = 4 out = dict(zip(combinations(range(n), 2), count()))Parece ser un poco más rápido. Prueba con n = 1000:
191.0 ms mozway 176.2 ms kelly 186.8 ms mozway 177.8 ms kelly 185.2 ms mozway 178.6 ms kellyCódigo ( ¡Pruébelo en línea! ):
from timeit import repeat from itertools import combinations, count def mozway(): return {k:v for v,k in enumerate(combinations(range(n), 2))} def kelly(): return dict(zip(combinations(range(n), 2), count())) n = 1000 for func in [mozway, kelly] * 3: t = min(repeat(func, number=1)) print('%5.1f ms ' % (t * 1e3), func.__name__)