crear - listas en python
Formateo de nĂºmeros consecutivos (5)
Estoy tratando de formatear una lista de enteros con Python y estoy teniendo algunas dificultades para lograr lo que me gustaría.
La entrada es una lista ordenada de enteros:
list = [1, 2, 3, 6, 8, 9]
Me gustaría que el resultado fuera una Cadena con el siguiente aspecto:
outputString = "1-3, 6, 8-9"
Hasta ahora todo lo que logré lograr es esto:
outputString = "1-2-3, 6, 8-9"
Tengo problemas para decirle a mi código que ignore un Int si ya era consecutivo.
Aquí está mi código hasta ahora:
def format(l):
i = 0
outputString = str(l[i])
for x in range(len(l)-1):
if l[i + 1] == l[i]+1 :
outputString += ''-'' + str(l[i+1])
else :
outputString += '', '' + str(l[i+1])
i = i + 1
return outputString
Gracias por su ayuda y comprensión :)
Dado que el otro tipo que publicó esta solución borró su respuesta ...
Aquí hay una solución de construcción de cadenas O(n)
:
def stringify(lst):
result = str(lst[0])
end = None
for index, num in enumerate(lst[1:]):
if num - 1 == lst[index]: # the slice shifts the index by 1 for us
end = str(num)
else:
if end:
result += ''-'' + end
end = None
result += '', '' + str(num)
# Catch the last term
if end:
result += ''-'' + str(num)
return result
Ver el repl.it
Esto parece un poco más corto que las respuestas actuales, pero sigue siendo bastante legible.
Podría haber una manera más agradable de hacerlo sin construir un objeto con un ciclo explícito, pero no podría pensar en uno.
L = [1, 2, 3, 6, 8, 9]
runs = [[str(L[0])]]
for first, second in zip(L, L[1:]):
if second == first + 1:
runs[-1].append(str(second))
else:
runs.append([str(second)])
result = ", ".join(["-".join(run) for run in runs])
No es la solución más fácil de leer, pero hace el trabajo. Uno puede primero determinar los saltos en sus datos (salto = la diferencia entre dos elementos es mayor que 1). Luego, recorre su lista original y recoge los elementos respectivos y los une a una cadena.
import numpy as np
l = np.array([1, 2, 3, 6, 8, 9])
# find indexes of jumps in your data
l_diff = np.where(np.diff(l) > 1)[0] + 1
# add one index which makes slicing easier later on
if l_diff[0] != 0:
l_diff = np.insert(l_diff, 0, 0)
# add all the data which are groups of consecutive values
res = []
for ix, i in enumerate(l_diff):
try:
sl = l[i:l_diff[ix + 1]]
if len(sl) > 1:
res.append([sl[0], sl[-1]])
else:
res.append(sl)
# means we reached end of l_diff
except IndexError:
sl = l[i:]
if len(sl) > 1:
res.append([sl[0], sl[-1]])
else:
res.append(sl)
# join the data accordingly, we first have to convert integers to strings
res = '', ''.join([''-''.join(map(str, ai)) for ai in res])
Entonces res
es
''1-3, 6, 8-9''
Puede usar groupby
y count
desde el módulo itertools
esta manera:
Editar:
Gracias al @asongtoruin
comentario. Para eliminar duplicados de la entrada, puede usar: sorted(set(a))
.
from itertools import groupby, count
a = [1, 2, 3, 6, 8, 9]
clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
for k in clustered:
if len(k) > 1:
print("{0}-{1}".format(k[0], k[-1]))
else:
print("{0}".format(k[0]))
Salida:
1-3
6
8-9
O tal vez puedas hacer algo como esto para tener una salida bonita:
from itertools import groupby, count
a = [1, 2, 3, 6, 8, 9]
clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
out = ", ".join(["{0}-{1}".format(k[0], k[-1]) if len(k) > 1 else "{0}".format(k[0]) for k in clustered ])
print(out)
Salida:
1-3, 6, 8-9
list=[1, 2, 3, 4, 6, 10, 11, 12, 13]
y=str(list[0])
for i in range(0, len(list)-1):
if list[i+1] == list[i]+1 :
y+= ''-'' + str(list[i + 1])
else:
y+= '','' + str(list[i + 1])
print y
z= y.split('','')
outputString= ''''
for i in z:
p=i.split(''-'')
if p[0] == p[len(p)-1]:
outputString = outputString + str(p[0]) + str('','')
else:
outputString = outputString + str(p[0]) + str(''-'') + str(p[len(p) - 1]) + str('','')
outputString = outputString[:len(outputString) - 1]
print ''final ans: '',outputString
agrega estas líneas después de tu código.