No he podido encontrar una explicación comprensible de cómo usar realmente la itertools.groupby()
función de Python . Lo que intento hacer es esto:
- Tome una lista: en este caso, los
lxml
elementos secundarios de un elemento objetivado - Dividirlo en grupos según algunos criterios.
- Luego, repita cada uno de estos grupos por separado.
He revisado la documentación y los ejemplos , pero he tenido problemas para intentar aplicarlos más allá de una simple lista de números.
Entonces, ¿cómo uso itertools.groupby()
? ¿Hay otra técnica que debería estar usando? También se agradecerán los indicadores de buena lectura de "prerrequisitos".
Respuestas:
NOTA IMPORTANTE: primero debe ordenar sus datos .
La parte que no entendí es que en el ejemplo de construcción
k
es la clave de agrupación actual yg
es un iterador que puede usar para iterar sobre el grupo definido por esa clave de agrupación. En otras palabras, elgroupby
iterador mismo devuelve iteradores.Aquí hay un ejemplo de eso, usando nombres de variables más claros:
Esto te dará el resultado:
En este ejemplo,
things
hay una lista de tuplas donde el primer elemento de cada tupla es el grupo al que pertenece el segundo elemento.La
groupby()
función toma dos argumentos: (1) los datos para agrupar y (2) la función para agruparlos.Aquí,
lambda x: x[0]
le indicagroupby()
que use el primer elemento en cada tupla como la clave de agrupación.En la
for
declaración anterior ,groupby
devuelve tres pares (clave, iterador de grupo), una vez para cada clave única. Puede usar el iterador devuelto para iterar sobre cada elemento individual en ese grupo.Aquí hay un ejemplo ligeramente diferente con los mismos datos, utilizando una lista de comprensión:
Esto te dará el resultado:
fuente
groupby(sorted(my_collection, key=lambda x: x[0]), lambda x: x[0]))
bajo la suposición de quemy_collection = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
y que se desean agrupar poranimal or plant
El ejemplo en los documentos de Python es bastante sencillo:
Entonces, en su caso, los datos son una lista de nodos,
keyfunc
es donde va la lógica de su función de criterios y luegogroupby()
agrupa los datos.Debe tener cuidado de ordenar los datos según los criterios antes de llamar
groupby
o no funcionará.groupby
El método en realidad solo itera a través de una lista y cada vez que la clave cambia, crea un nuevo grupo.fuente
keyfunc
y dijiste "sí, sé exactamente qué es eso porque esta documentación es bastante sencilla"? ¡Increíble!itertools.groupby
es una herramienta para agrupar elementos.De los documentos , recogemos aún más lo que podría hacer:
groupby
los objetos producen pares clave-grupo donde el grupo es un generador.Caracteristicas
Comparaciones
Usos
Nota: Varios de los últimos ejemplos se derivan de PyCon de Víctor Terrón (hablar) (español) , "Kung Fu en la madrugada con itertools". Vea también el
groupby
código fuente escrito en C.* Una función donde todos los elementos se pasan y comparan, influyendo en el resultado. Otros objetos con funciones clave incluyen
sorted()
,max()
ymin()
.Respuesta
fuente
[''.join(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
.list()
,tuple()
) o consumirse en un bucle / comprensión para mostrar el contenido. Estas son redundancias que el autor probablemente excluyó para conservar espacio.Un buen truco con groupby es ejecutar la codificación de longitud en una línea:
le dará una lista de 2 tuplas donde el primer elemento es el carácter y el segundo es el número de repeticiones.
Editar: Tenga en cuenta que esto es lo que se separa
itertools.groupby
de laGROUP BY
semántica de SQL : itertools no clasifica (y en general no puede) el iterador por adelantado, por lo que los grupos con la misma "clave" no se fusionan.fuente
Otro ejemplo:
resultados en
Tenga en cuenta que igroup es un iterador (un sub-iterador como lo llama la documentación).
Esto es útil para fragmentar un generador:
Otro ejemplo de groupby: cuando las claves no están ordenadas. En el siguiente ejemplo, los elementos en xx se agrupan por valores en yy. En este caso, primero se genera un conjunto de ceros, seguido de un conjunto de unos, seguido nuevamente por un conjunto de ceros.
Produce:
fuente
ADVERTENCIA:
La lista de sintaxis (groupby (...)) no funcionará de la manera prevista. Parece destruir los objetos iteradores internos, por lo que usar
Producirá:
En lugar de list (groupby (...)), intente [(k, list (g)) para k, g en groupby (...)], o si usa esa sintaxis con frecuencia,
y obtenga acceso a la funcionalidad groupby mientras evita esos molestos iteradores (para datos pequeños) todos juntos.
fuente
Me gustaría dar otro ejemplo donde groupby sin clasificación no funciona. Adaptado del ejemplo de James Sulak
la salida es
Hay dos grupos con vehículo, mientras que uno podría esperar solo un grupo
fuente
@CaptSolo, probé tu ejemplo, pero no funcionó.
Salida:
Como puede ver, hay dos o y dos e, pero se agruparon en grupos separados. Fue entonces cuando me di cuenta de que necesita ordenar la lista que pasó a la función groupby. Entonces, el uso correcto sería:
Salida:
Solo recordando, si la lista no está ordenada, ¡la función groupby no funcionará !
fuente
fuente
Puede usar groupby para agrupar cosas para iterar. Le da a groupby un iterable, y una función de tecla opcional / invocable mediante la cual verificar los elementos a medida que salen del iterable, y devuelve un iterador que da una tupla de dos tuplas del resultado de la clave invocable y los elementos reales en Otro iterable. De la ayuda:
Aquí hay un ejemplo de groupby usando una rutina para agrupar por un conteo, usa una clave invocable (en este caso
coroutine.send
) para escupir el conteo por la cantidad de iteraciones y un sub-iterador agrupado de elementos:huellas dactilares
fuente
Un ejemplo útil que encontré puede ser útil:
Entrada de muestra: 14445221
Salida de muestra: (1,1) (3,4) (1,5) (2,2) (1,1)
fuente
Esta implementación básica me ayudó a entender esta función. Espero que ayude a otros también:
fuente
Puede escribir su propia función groupby:
fuente