python - example - Dividir una lista en tamaños especificados por otra lista
itertools combinations example (3)
Puedes hacerlo de esta manera:
>>> x = list(range(10))
>>> num_items = [9, 1, 1]
>>> s = 0
>>> for i in num_items:
... print x[s:s + i]
... s += i
...
Huellas dactilares:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[9]
[]
Digamos que hay una lista X y otra lista num_items
que especifican el número de elementos que deberían estar en la sublista, puedo dividir la lista manualmente como tal:
>>> x = list(range(10))
>>> x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> num_items = [4, 4, 2]
>>> slice1 = x[:num_items[0]]
>>> slice2 = x[len(slice1):len(slice1)+num_items[1]]
>>> slice3 = x[len(slice1)+len(slice2):]
>>> slice1, slice2, slice3
([0, 1, 2, 3], [4, 5, 6, 7], [8, 9])
Habrá dos casos en los que las últimas secciones pueden ser problemáticas, por ejemplo, pero eso se puede resolver con la lista vacía dado que codigo manualmente las 3 rebanadas:
>>> num_items = [9, 1, 1]
>>> slice1 = x[:num_items[0]]
>>> slice2 = x[len(slice1):len(slice1)+num_items[1]]
>>> slice3 = x[len(slice1)+len(slice2):]
>>> slice1, slice2, slice3
([0, 1, 2, 3, 4, 5, 6, 7, 8], [9], [])
¿Qué pasa si hay 4 sectores, por ejemplo:
>>> num_items = [9, 1, 1, 2]
>>> slice1 = x[:num_items[0]]
>>> slice2 = x[len(slice1):len(slice1)+num_items[1]]
>>> slice3 = x[len(slice1)+len(slice2):len(slice1)+len(slice2)+num_items[2]]
>>> slice4 = x[len(slice1)+len(slice2)+len(slice3): len(slice)+len(slice2)+len(slice3)+num_items[3]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type ''type'' has no len()
El resultado deseado sería agregar una lista vacía a la cuarta porción, es decir:
>>> slice1, slice2, slice3, slice4
([0, 1, 2, 3, 4, 5, 6, 7, 8], [9], [], [])
Si num_items
requiere elementos menores que la longitud de X, simplemente devuelve hasta la suma de num_items
, es decir,
>>> num_items = [4, 4]
>>> slice1, slice2
([0, 1, 2, 3], [4, 5, 6, 7])
La pregunta principal es: ¿hay alguna forma de dividir los sectores sin codificar manualmente las divisiones? (La respuesta para cubrir el caso en el que num_items
solicita más elementos que en X, en ese caso, deben devolverse sublistas vacías)
Tenga en cuenta que la longitud de X puede ser bastante grande (es decir,> 10,000,000,000) pero la longitud de num_items
varía de 1 a 100 =)
Una manera simple pero simple de hacer eso.
>>> x = list(range(10))
>>> num_items = [2,3,4,1]
>>> cur_sum = 0
>>> slices = []
>>> for i in num_items:
... slices.append(x[cur_sum:cur_sum+i])
... cur_sum += i
...
>>> slices
[[0, 1], [2, 3, 4], [5, 6, 7, 8], [9]]
Aquí tienes un enfoque diferente:
[[x.pop(0) for _ in x[:s]] for s in num_items]
Ejemplos:
>>> x = range(10)
>>> n = [9, 1, 1]
>>> [[x.pop(0) for y in x[:s]] for s in n]
[[0, 1, 2, 3, 4, 5, 6, 7, 8], [9], []]
>>> x = range(10)
>>> n = [2, 2, 2, 2, 2, 2]
>>> [[x.pop(0) for y in x[:s]] for s in n]
[[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], []]
>>> x = range(10)
>>> n = [3, 4, 5, 2]
>>> [[x.pop(0) for y in x[:s]] for s in n]
[[0, 1, 2], [3, 4, 5, 6], [7, 8, 9], []] # Notice here how slice 5 only returns 3 numbers because there are only 3 numbers left in x