Use conjuntos para contar ocurrencias en Python
Refactorice un algoritmo de tres pasos en una sola línea usando conjuntos.
¿Qué son conjuntos?
En informática, los conjuntos son una colección (contenedores) de ciertos valores, sin ningún orden concreto ni valores repetidos. Su correspondencia en las matemáticas sería el conjunto finito. Sin tener en cuenta la secuencia, ni el hecho de que no haya valores repetidos, se asemeja a una lista.
Cómo no amar la flexibilidad de Python. Son momentos elegantes de esa sensación “¡AJÁ!” en los que una implementación inteligente de herramientas nativas produce resultados simplificados que hasta hacen sonreír.
Supongamos que nos toca analizar un conjunto de datos: una lista de diccionarios donde se necesitaba contar un término llamado status
. Hemos hecho esto en otros lenguajes antes y tenemos un algoritmo que hemos transferido a Python. Pero nos damos cuenta de que había una forma mejor:
Entrada y salida de muestra
Antes de pasar a los algoritmos, aquí hay una entrada y una salida de muestra para ayudar a enmarcar las siguientes soluciones.
Observe cómo la función identificará todos los diferentes valores de estado y devolverá un diccionario de recuentos para cada valor. Ahora, revisemos el algoritmo agnóstico del lenguaje y luego profundicemos en la mejor solución de Python.
Algoritmo de recuento de ocurrencias
El siguiente algoritmo se puede escribir de diferentes maneras, pero esencialmente lo que debe suceder es que debemos realizar un seguimiento de todos los diferentes valores en el estado e incrementar los conteos a medida que avanzamos. Escrito dentro de una función, se parece a esto.
Rastreando la función, comenzamos pasando dos argumentos: la lista para iterar y el valor del término que analizaremos. Dentro de la definición de la función creamos un diccionario vacío y mientras iteramos sobre la lista, verificamos si la row[term]
, que es el valor del status
, no existe como término en el diccionario de counts
. Si no existe, lo sumamos e inicializamos el recuento a 0. Continuando, incrementamos el recuento apropiado y devolvemos el diccionario.
Observe en el ejemplo que el status
no está codificado, sino que se usó una variable para que la función sea un poco más fácil de usar en múltiples escenarios.
Usar conjuntos y comprensiones
El mecanismo condensado del que hablamos utiliza conjuntos y comprensiones. En Python, un conjunto es un tipo de datos donde cada elemento debe ser único. Esto significa que no pueden existir duplicados en un conjunto. Las comprensiones son una convención abreviada que combina la creación de un nuevo punto de datos mediante la iteración de otro. Las listas por comprensión son la implementación más popular, pero también existen las comprensiones de conjuntos y las comprensiones de diccionario.
Aunque esta solución es una sola línea, usaremos la misma configuración de funciones para una refactorización perfecta.
Ahora, esta es una frase densa, así que vamos a deconstruirla. Usamos las tres comprensiones para los siguientes propósitos:
- Diccionario: crea el objeto de devolución
- Establecer: identificar valores únicos de
status
- Lista: iterar sobre el conjunto de datos y filtrar según el estado
Observe la parte de la línea 4 que dice {x[term] for x in my_list}
. Esto está creando un conjunto de valores de status
que se usa para iterar al crear el diccionario de retorno. Por lo tanto, por qué la línea 3 comienza con val:
que es el elemento temporal que se usa al iterar sobre el conjunto.
En cuanto al recuento real, lo que se establece como la definición de val
, tenemos el valor real del status
, por lo que necesitamos encontrar las filas que coincidan con ese valor. Aquí es donde entra en juego la comprensión de la lista. Repetimos sobre my_list
, asignando el elemento temporal a la row
, pero solo incluimos los elementos donde row[term]
es igual a val
. Realmente no importa en qué establezcamos el valor dentro de la comprensión de la lista, así que solo usé el valor booleano True
. Finalmente, necesitamos tomar la longitud de la lista creada para usar la función len()
.
Conclusión
Quizás no haya probado la velocidad de ambas soluciones, por lo que, por lo que sé, la primera fue en realidad más eficiente. Sin embargo, este tipo de ejercicios mentales son excelentes para flexionar esa parte del cerebro que resuelve problemas y aprender a ver los problemas a través de la lente del kit de herramientas de Python.