supongamos que tengo cantidades de frutas de diferentes colores, por ejemplo, 24 plátanos azules, 12 manzanas verdes, 0 fresas azules y así sucesivamente. Me gustaría organizarlos en una estructura de datos en Python que permita una fácil selección y clasificación. Mi idea era ponerlos en un diccionario con tuplas como claves, por ejemplo,
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
o incluso diccionarios, por ejemplo,
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
Me gustaría recuperar una lista de todas las frutas azules o plátanos de todos los colores, por ejemplo, o ordenar este diccionario por el nombre de la fruta. ¿Hay formas de hacer esto de una manera limpia?
Bien podría ser que los diccionarios con tuplas como claves no sean la forma adecuada de manejar esta situación.
¡Todas las sugerencias son bienvenidas!
Respuestas:
Personalmente, una de las cosas que me encanta de Python es la combinación tuple-dict. Lo que tiene aquí es efectivamente una matriz 2d (donde x = nombre de la fruta ey = color), y generalmente soy partidario del dictado de tuplas para implementar matrices 2d, al menos cuando algo como
numpy
o una base de datos no es más apropiado . En resumen, creo que tienes un buen enfoque.Tenga en cuenta que no puede usar dictados como claves en un dictado sin hacer un trabajo adicional, por lo que no es una muy buena solución.
Dicho esto, también debería considerar namedtuple () . De esa forma podrías hacer esto:
Ahora puedes usar tu dictado de fruitcount:
Otros trucos:
Haciendo eco de chmullig, para obtener una lista de todos los colores de una fruta, tendría que filtrar las claves, es decir
fuente
name='banana'
?bananas = filter(lambda fruit: fruit.name=='banana', fruits)
obananas = [fruit for fruit in fruits if fruit.name=='banana']
. Ésta es una forma en la que los dictados anidados son potencialmente más eficientes; todo se reduce a las formas en que planea usar los datos.count
Su mejor opción será crear una estructura de datos simple para modelar lo que tiene. Luego, puede almacenar estos objetos en una lista simple y ordenarlos / recuperarlos de la forma que desee.
Para este caso, usaría la siguiente clase:
Luego, simplemente puede construir instancias de "Fruta" y agregarlas a una lista, como se muestra de la siguiente manera:
La lista simple
fruits
será mucho más fácil, menos confusa y mejor mantenida.Algunos ejemplos de uso:
Todas las salidas a continuación son el resultado después de ejecutar el fragmento de código dado seguido de:
Lista sin clasificar:
Muestra:
Ordenado alfabéticamente por nombre:
Muestra:
Ordenados por cantidad:
Muestra:
Donde color == rojo:
Muestra:
fuente
Base de datos, dictado de dictados, diccionario de lista de diccionarios, tupla con nombre (es una subclase), sqlite, redundancia ... No creía lo que veía. Qué más ?
¡Si! pensé
Entonces, en mi opinión, una lista de tuplas es suficiente:
resultado
fuente
Un diccionario probablemente no sea lo que debería usar en este caso. Una biblioteca con más funciones sería una mejor alternativa. Probablemente una base de datos real. El más fácil sería sqlite . Puede mantener todo en la memoria pasando la cadena ': memoria:' en lugar de un nombre de archivo.
Si desea continuar por este camino, puede hacerlo con los atributos adicionales en la clave o el valor. Sin embargo, un diccionario no puede ser la clave de otro diccionario, pero una tupla sí. Los documentos explican lo que está permitido. Debe ser un objeto inmutable, que incluya cadenas, números y tuplas que contengan solo cadenas y números (y más tuplas que contengan solo esos tipos de forma recursiva ...).
Podría hacer su primer ejemplo con
d = {('apple', 'red') : 4}
, pero será muy difícil consultar lo que desea. Necesitarías hacer algo como esto:fuente
Con claves como tuplas, simplemente filtre las claves con el segundo componente dado y ordénelas:
La clasificación funciona porque las tuplas tienen un orden natural si sus componentes tienen un orden natural.
Con las claves como objetos bastante completos, simplemente filtra por
k.color == 'blue'
.Realmente no puede usar dictados como claves, pero puede crear una clase más simple como
class Foo(object): pass
y agregarle cualquier atributo sobre la marcha:Estas instancias pueden servir como claves de dictado, ¡pero cuidado con su mutabilidad!
fuente
Podría tener un diccionario donde las entradas sean una lista de otros diccionarios:
Salida:
Editar: como señaló eumiro, podría usar un diccionario de diccionarios:
Salida:
fuente
Este tipo de datos se extrae de manera eficiente de una estructura de datos similar a Trie. También permite una clasificación rápida. Sin embargo, es posible que la eficiencia de la memoria no sea tan buena.
Un trie tradicional almacena cada letra de una palabra como un nodo en el árbol. Pero en su caso, su "alfabeto" es diferente. Estás almacenando cadenas en lugar de caracteres.
podría verse algo como esto:
ver este enlace: trie en python
fuente
Desea utilizar dos teclas de forma independiente, por lo que tiene dos opciones:
Almacene los datos de forma redundante con dos dictados como
{'banana' : {'blue' : 4, ...}, .... }
y{'blue': {'banana':4, ...} ...}
. Luego, buscar y ordenar es fácil, pero debe asegurarse de modificar los dictados juntos.Guárdelo solo un dict y luego escriba funciones que iteren sobre ellos, por ejemplo:
fuente