Python-Encuentra los mismos valores en una lista y agrupa una nueva lista
duplicates append (6)
Estoy atascado al resolver esto y me pregunto si alguien podría señalarme en la dirección correcta ...
De esta lista:
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
Estoy tratando de crear:
L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]
Cualquier valor que se encuentre que es el mismo se agrupa en su propia lista secundaria. Aquí está mi intento hasta ahora, ¿estoy pensando que debería usar un bucle while?
global n
n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list
l = [] #Empty list to append values to
def compare(val):
""" This function receives index values
from the n list (n[0] etc) """
global valin
valin = val
global count
count = 0
for i in xrange(len(n)):
if valin == n[count]: # If the input value i.e. n[x] == n[iteration]
temp = valin, n[count]
l.append(temp) #append the values to a new list
count +=1
else:
count +=1
for x in xrange (len(n)):
compare(n[x]) #pass the n[x] to compare function
Alguien menciona para N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1]
obtendrá [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]
En otras palabras, cuando los números de la lista no están en orden o es una lista de desorden, no está disponible.
Así que tengo mejor respuesta para resolver este problema.
from collections import Counter
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
C = Counter(N)
print [ [k,]*v for k,v in C.items()]
Estás supercomplicando esto.
Lo que desea hacer es: para cada valor, si es el mismo que el último valor, simplemente agréguelo a la lista de los últimos valores; de lo contrario, crea una nueva lista. Puedes traducir ese inglés directamente a Python:
new_list = []
for value in old_list:
if new_list and new_list[-1][0] == value:
new_list[-1].append(value)
else:
new_list.append([value])
Incluso hay formas más simples de hacerlo si está dispuesto a ser un poco más abstracto, por ejemplo, mediante el uso de las funciones de agrupación en itertools
. Pero esto debería ser fácil de entender.
Si realmente necesita hacer esto con un bucle while, puede convertir cualquier bucle for
en un bucle while como este:
for value in iterable:
do_stuff(value)
iterator = iter(iterable)
while True:
try:
value = next(iterator)
except StopIteration:
break
do_stuff(value)
O, si sabe que lo iterable es una secuencia, puede usar un bucle while
más simple:
index = 0
while index < len(sequence):
value = sequence[index]
do_stuff(value)
index += 1
Pero ambos hacen que su código sea menos legible, menos pitónico, más complicado, menos eficiente, más fácil de equivocarse, etc.
Mantener la calma y usar itertools.groupby
:
from itertools import groupby
N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
print([list(j) for i, j in groupby(N)])
Salida:
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
Nota al margen: Evite el uso de la variable global cuando no lo necesite .
Otra solución ligeramente diferente que no depende de itertools:
#!/usr/bin/env python
def group(items):
"""
groups a sorted list of integers into sublists based on the integer key
"""
if len(items) == 0:
return []
grouped_items = []
prev_item, rest_items = items[0], items[1:]
subgroup = [prev_item]
for item in rest_items:
if item != prev_item:
grouped_items.append(subgroup)
subgroup = []
subgroup.append(item)
prev_item = item
grouped_items.append(subgroup)
return grouped_items
print group([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
Puede usar itertools.groupby
junto con una lista de comprensión
>>> l = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
>>> [list(v) for k,v in itertools.groupby(l)]
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
Esto se puede asignar a la variable L
como en
L = [list(v) for k,v in itertools.groupby(l)]
Puedes hacerlo usando numpy también:
import numpy as np
N = np.array([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
counter = np.arange(1, np.alen(N))
L = np.split(N, counter[N[1:]!=N[:-1]])
La ventaja de este método es que cuando tiene otra lista relacionada con N y desea dividirla de la misma manera.