Creando una matriz de números que sumn un número dado

He estado trabajando en algunos guiones rápidos y sucios para hacer algunos de mis deberes de química, y uno de ellos itera a través de listas de una longitud constante donde todos los elementos se sumn a una constante dada. Para cada uno, verifico si cumplen con algunos criterios adicionales y los agrego a otra lista.

Encontré una manera de cumplir con los criterios de la sum, pero se ve horrible , y estoy seguro de que hay algún tipo de momento de enseñanza aquí:

# iterate through all 11-element lists where the elements sum to 8. for a in range(8+1): for b in range(8-a+1): for c in range(8-a-b+1): for d in range(8-ab-c+1): for e in range(8-abc-d+1): for f in range(8-abcd-e+1): for g in range(8-abcde-f+1): for h in range(8-abcdef-g+1): for i in range(8-abcdefg-h+1): for j in range(8-abcdefgh-i+1): k = 8-(a+b+c+d+e+f+g+h+i+j) x = [a,b,c,d,e,f,g,h,i,j,k] # see if x works for what I want 

Aquí hay un generador recursivo que produce las listas en orden lexicográfico. Dejando exact como True da el resultado solicitado donde cada sum == límite; establecer exact en False da todas las listas con 0 <= suma <= límite. La recursión aprovecha esta opción para producir los resultados intermedios.

 def lists_with_sum(length, limit, exact=True): if length: for l in lists_with_sum(length-1, limit, False): gap = limit-sum(l) for i in range(gap if exact else 0, gap+1): yield l + [i] else: yield [] 

Solución genérica, recursiva:

 def get_lists_with_sum(length, my_sum): if my_sum == 0: return [[0 for _ in range(length)]] if not length: return [[]] elif length == 1: return [[my_sum]] else: lists = [] for i in range(my_sum+1): rest = my_sum - i sublists = get_lists_with_sum(length-1, rest) for sl in sublists: sl.insert(0, i) lists.append(sl) return lists print get_lists_with_sum(11, 8)