una tuplas metodos listas lista las intervalos funcionan funcion for definir datos como almacenar python list sequence

metodos - lista de tuplas python



Lista de división de Python basada en números faltantes en una secuencia (5)

Estoy buscando la forma más pitónica de dividir una lista de números en listas más pequeñas en función de un número que falta en la secuencia. Por ejemplo, si la lista inicial era:

seq1 = [1, 2, 3, 4, 6, 7, 8, 9, 10]

La función produciría:

[[1, 2, 3, 4], [6, 7, 8, 9, 10]]

o

seq2 = [1, 2, 4, 5, 6, 8, 9, 10]

resultaría en:

[[1, 2], [4, 5, 6], [8, 9, 10]]


De la documentación de python :

>>> # Find runs of consecutive numbers using groupby. The key to the solution >>> # is differencing with a range so that consecutive numbers all appear in >>> # same group. >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): ... print map(itemgetter(1), g) ... [1] [4, 5, 6] [10] [15, 16, 17, 18] [22] [25, 26, 27, 28]

La función groupby () del módulo itertools genera un descanso cada vez que la función clave cambia su valor de retorno. El truco es que el valor de retorno es el número en la lista menos la posición del elemento en la lista. Esta diferencia cambia cuando hay una brecha en los números.

La función itemgetter () es del módulo del operador , tendrá que importar esto y el módulo itertools para que este ejemplo funcione.

Ejemplo completo con sus datos:

>>> from operator import itemgetter >>> from itertools import * >>> seq2 = [1, 2, 4, 5, 6, 8, 9, 10] >>> list = [] >>> for k, g in groupby(enumerate(seq2), lambda (i,x):i-x): ... list.append(map(itemgetter(1), g)) ... >>> print list [[1, 2], [4, 5, 6], [8, 9, 10]]

O como una lista de comprensión:

>>> [map(itemgetter(1), g) for k, g in groupby(enumerate(seq2), lambda (i,x):i-x)] [[1, 2], [4, 5, 6], [8, 9, 10]]


Esta es una solución que funciona en Python 3 (basada en respuestas anteriores que solo funcionan en Python 2).

>>> from operator import itemgetter >>> from itertools import * >>> groups = [] >>> for k, g in groupby(enumerate(seq2), lambda x: x[0]-x[1]): >>> groups.append(list(map(itemgetter(1), g))) ... >>> print(groups) [[1, 2], [4, 5, 6], [8, 9, 10]]

o como una lista de comprensión

>>> [list(map(itemgetter(1), g)) for k, g in groupby(enumerate(seq2), lambda x: x[0]-x[1])] [[1, 2], [4, 5, 6], [8, 9, 10]]

Se necesitaron cambios porque

  • Eliminación del parámetro tupla desempaquetado PEP 3113
  • Mapa que devuelve un iterador en lugar de una lista

Me gusta este mejor porque no requiere ninguna biblioteca adicional o tratamiento especial para el primer caso:

a = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 17, 18, 20, 21, 22] b = [] subList = [] prev_n = -1 for n in a: if prev_n+1 != n: # end of previous subList and beginning of next if subList: # if subList already has elements b.append(subList) subList = [] subList.append(n) prev_n = n if subList: b.append(subList) print a print b

Salida:

[1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 17, 18, 20, 21, 22]

[[1, 2, 3, 4, 5, 6, 7, 8], [10, 11, 12], [15, 16, 17, 18], [20, 21, 22]]


Mi manera

alist = [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 17, 18, 20, 21, 22] newlist = [] start = 0 end = 0 for index,value in enumerate(alist): if index < len(alist)-1: if alist[index+1]> value+1: end = index +1 newlist.append(alist[start:end]) start = end else: newlist.append(alist[start: len(alist)]) print(newlist)

Resultado

[[1, 2, 3, 4, 5, 6, 7, 8], [10, 11, 12], [15, 16, 17, 18], [20, 21, 22]]


Otra opción que no lo necesita, etcétera.

>>> data = [1, 4, 5, 6, 10, 15, 16, 17, 18, 22, 25, 26, 27, 28] >>> spl = [0]+[i for i in range(1,len(data)) if data[i]-data[i-1]>1]+[None] >>> [data[b:e] for (b, e) in [(spl[i-1],spl[i]) for i in range(1,len(spl))]] ... [[1], [4, 5, 6], [10], [15, 16, 17, 18], [22], [25, 26, 27, 28]]