varias una tupla tabla para ordenar listas lista leer funcion ascendentemente anidadas alfabeticamente python select dictionary key tuples

una - Python: Tuples/diccionarios como teclas, seleccionar, ordenar



ordenar una tupla python (8)

Base de datos, dict of dicts, diccionario de la lista de diccionarios, llamada tuple (es una subclase), sqlite, redundancy ... No creí en mis ojos. Qué más ?

"Bien podría ser que los diccionarios con tuplas como claves no sean la forma adecuada de manejar esta situación".

"Mi intuición es que una base de datos es excesiva para las necesidades del OP";

¡Sí! pensé

Entonces, en mi opinión, una lista de tuplas es suficiente:

from operator import itemgetter li = [ (''banana'', ''blue'' , 24) , (''apple'', ''green'' , 12) , (''strawberry'', ''blue'' , 16 ) , (''banana'', ''yellow'' , 13) , (''apple'', ''gold'' , 3 ) , (''pear'', ''yellow'' , 10) , (''strawberry'', ''orange'' , 27) , (''apple'', ''blue'' , 21) , (''apple'', ''silver'' , 0 ) , (''strawberry'', ''green'' , 4 ) , (''banana'', ''brown'' , 14) , (''strawberry'', ''yellow'' , 31) , (''apple'', ''pink'' , 9 ) , (''strawberry'', ''gold'' , 0 ) , (''pear'', ''gold'' , 66) , (''apple'', ''yellow'' , 9 ) , (''pear'', ''brown'' , 5 ) , (''strawberry'', ''pink'' , 8 ) , (''apple'', ''purple'' , 7 ) , (''pear'', ''blue'' , 51) , (''chesnut'', ''yellow'', 0 ) ] print set( u[1] for u in li ),'': all potential colors'' print set( c for f,c,n in li if n!=0),'': all effective colors'' print [ c for f,c,n in li if f==''banana'' ],'': all potential colors of bananas'' print [ c for f,c,n in li if f==''banana'' and n!=0],'': all effective colors of bananas'' print print set( u[0] for u in li ),'': all potential fruits'' print set( f for f,c,n in li if n!=0),'': all effective fruits'' print [ f for f,c,n in li if c==''yellow'' ],'': all potential fruits being yellow'' print [ f for f,c,n in li if c==''yellow'' and n!=0],'': all effective fruits being yellow'' print print len(set( u[1] for u in li )),'': number of all potential colors'' print len(set(c for f,c,n in li if n!=0)),'': number of all effective colors'' print len( [c for f,c,n in li if f==''strawberry'']),'': number of potential colors of strawberry'' print len( [c for f,c,n in li if f==''strawberry'' and n!=0]),'': number of effective colors of strawberry'' print # sorting li by name of fruit print sorted(li),'' sorted li by name of fruit'' print # sorting li by number print sorted(li, key = itemgetter(2)),'' sorted li by number'' print # sorting li first by name of color and secondly by name of fruit print sorted(li, key = itemgetter(1,0)),'' sorted li first by name of color and secondly by name of fruit'' print

resultado

set([''blue'', ''brown'', ''gold'', ''purple'', ''yellow'', ''pink'', ''green'', ''orange'', ''silver'']) : all potential colors set([''blue'', ''brown'', ''gold'', ''purple'', ''yellow'', ''pink'', ''green'', ''orange'']) : all effective colors [''blue'', ''yellow'', ''brown''] : all potential colors of bananas [''blue'', ''yellow'', ''brown''] : all effective colors of bananas set([''strawberry'', ''chesnut'', ''pear'', ''banana'', ''apple'']) : all potential fruits set([''strawberry'', ''pear'', ''banana'', ''apple'']) : all effective fruits [''banana'', ''pear'', ''strawberry'', ''apple'', ''chesnut''] : all potential fruits being yellow [''banana'', ''pear'', ''strawberry'', ''apple''] : all effective fruits being yellow 9 : number of all potential colors 8 : number of all effective colors 6 : number of potential colors of strawberry 5 : number of effective colors of strawberry [(''apple'', ''blue'', 21), (''apple'', ''gold'', 3), (''apple'', ''green'', 12), (''apple'', ''pink'', 9), (''apple'', ''purple'', 7), (''apple'', ''silver'', 0), (''apple'', ''yellow'', 9), (''banana'', ''blue'', 24), (''banana'', ''brown'', 14), (''banana'', ''yellow'', 13), (''chesnut'', ''yellow'', 0), (''pear'', ''blue'', 51), (''pear'', ''brown'', 5), (''pear'', ''gold'', 66), (''pear'', ''yellow'', 10), (''strawberry'', ''blue'', 16), (''strawberry'', ''gold'', 0), (''strawberry'', ''green'', 4), (''strawberry'', ''orange'', 27), (''strawberry'', ''pink'', 8), (''strawberry'', ''yellow'', 31)] sorted li by name of fruit [(''apple'', ''silver'', 0), (''strawberry'', ''gold'', 0), (''chesnut'', ''yellow'', 0), (''apple'', ''gold'', 3), (''strawberry'', ''green'', 4), (''pear'', ''brown'', 5), (''apple'', ''purple'', 7), (''strawberry'', ''pink'', 8), (''apple'', ''pink'', 9), (''apple'', ''yellow'', 9), (''pear'', ''yellow'', 10), (''apple'', ''green'', 12), (''banana'', ''yellow'', 13), (''banana'', ''brown'', 14), (''strawberry'', ''blue'', 16), (''apple'', ''blue'', 21), (''banana'', ''blue'', 24), (''strawberry'', ''orange'', 27), (''strawberry'', ''yellow'', 31), (''pear'', ''blue'', 51), (''pear'', ''gold'', 66)] sorted li by number [(''apple'', ''blue'', 21), (''banana'', ''blue'', 24), (''pear'', ''blue'', 51), (''strawberry'', ''blue'', 16), (''banana'', ''brown'', 14), (''pear'', ''brown'', 5), (''apple'', ''gold'', 3), (''pear'', ''gold'', 66), (''strawberry'', ''gold'', 0), (''apple'', ''green'', 12), (''strawberry'', ''green'', 4), (''strawberry'', ''orange'', 27), (''apple'', ''pink'', 9), (''strawberry'', ''pink'', 8), (''apple'', ''purple'', 7), (''apple'', ''silver'', 0), (''apple'', ''yellow'', 9), (''banana'', ''yellow'', 13), (''chesnut'', ''yellow'', 0), (''pear'', ''yellow'', 10), (''strawberry'', ''yellow'', 31)] sorted li first by name of color and secondly by name of fruit

supongamos que tengo cantidades de frutas de diferentes colores, por ejemplo, 24 plátanos azules, 12 manzanas verdes, 0 fresas azules, etc. 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?

Es muy posible que los diccionarios con tuplas como claves no sean la forma adecuada de manejar esta situación.

Todas las sugerencias son bienvenidas!


Con las teclas como tuplas, solo filtra las claves con el segundo componente dado y ordene:

blue_fruit = sorted([k for k in data.keys() if k[1] == ''blue'']) for k in blue_fruit: print k[0], data[k] # prints ''banana 24'', etc

La ordenación funciona porque las tuplas tienen un orden natural si sus componentes tienen un orden natural.

Con las teclas como objetos bastante completos, simplemente filtra por k.color == ''blue'' .

Realmente no se pueden usar dictados como claves, pero se puede crear una clase más simple como class Foo(object): pass y agregarle atributos sobre la marcha:

k = Foo() k.color = ''blue''

Estas instancias pueden servir como claves dict pero ten cuidado con su mutabilidad.


Desea usar dos claves de forma independiente, por lo que tiene dos opciones:

  1. Almacene los datos de forma redundante con dos dictados como {''banana'' : {''blue'' : 4, ...}, .... } y {''blue'': {''banana'':4, ...} ...} . Entonces, buscar y ordenar es fácil, pero debes asegurarte de modificar los dicts juntos.

  2. Almacénelo solo en un dict y luego escriba funciones que iteren sobre ellos, por ej .:

    d = {''banana'' : {''blue'' : 4, ''yellow'':6}, ''apple'':{''red'':1} } blueFruit = [(fruit,d[fruit][''blue'']) if d[fruit].has_key(''blue'') for fruit in d.keys()]


Este tipo de datos se extrae eficientemente de una estructura de datos tipo Trie. También permite una clasificación rápida. Sin embargo, la eficiencia de la memoria puede no ser tan buena.

Un trie tradicional almacena cada letra de una palabra como un nodo en el árbol. Pero en tu caso tu "alfabeto" es diferente. Está almacenando cadenas en lugar de caracteres.

podría ser algo como esto:

root: Root /|/ / | / / | / fruit: Banana Apple Strawberry / | | / / | | / color: Blue Yellow Green Blue / | | / / | | / end: 24 100 12 0

ver este enlace: trie en python


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 yy = color), y generalmente soy partidario de la dict de tuplas para implementar matrices en 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 dicts como teclas en un dict sin hacer un trabajo extra, por lo que esa no es una solución muy buena.

Dicho esto, también debes considerar namedtuple() . De esa manera podrías hacer esto:

>>> from collections import namedtuple >>> Fruit = namedtuple("Fruit", ["name", "color"]) >>> f = Fruit(name="banana", color="red") >>> print f Fruit(name=''banana'', color=''red'') >>> f.name ''banana'' >>> f.color ''red''

Ahora puede usar su dict de fruitcount:

>>> fruitcount = {Fruit("banana", "red"):5} >>> fruitcount[f] 5

Otros trucos:

>>> fruits = fruitcount.keys() >>> fruits.sort() >>> print fruits [Fruit(name=''apple'', color=''green''), Fruit(name=''apple'', color=''red''), Fruit(name=''banana'', color=''blue''), Fruit(name=''strawberry'', color=''blue'')] >>> fruits.sort(key=lambda x:x.color) >>> print fruits [Fruit(name=''banana'', color=''blue''), Fruit(name=''strawberry'', color=''blue''), Fruit(name=''apple'', color=''green''), Fruit(name=''apple'', color=''red'')]

Haciéndose eco de chmullig, para obtener una lista de todos los colores de una fruta, tendría que filtrar las claves, es decir,

bananas = [fruit for fruit in fruits if fruit.name==''banana'']


Podría tener un diccionario donde las entradas son una lista de otros diccionarios:

fruit_dict = dict() fruit_dict[''banana''] = [{''yellow'': 24}] fruit_dict[''apple''] = [{''red'': 12}, {''green'': 14}] print fruit_dict

Salida:

{''banana'': [{''amarillo'': 24}], ''manzana'': [{''rojo'': 12}, {''verde'': 14}]}

Editar: Como señaló Eumiro, podrías usar un diccionario de diccionarios:

fruit_dict = dict() fruit_dict[''banana''] = {''yellow'': 24} fruit_dict[''apple''] = {''red'': 12, ''green'': 14} print fruit_dict

Salida:

{''banana'': {''amarillo'': 24}, ''manzana'': {''verde'': 14, ''rojo'': 12}}


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:

class Fruit: def __init__(self, name, color, quantity): self.name = name self.color = color self.quantity = quantity def __str__(self): return "Name: %s, Color: %s, Quantity: %s" % / (self.name, self.color, self.quantity)

Luego puede simplemente construir instancias "Frutas" y agregarlas a una lista, como se muestra de la siguiente manera:

fruit1 = Fruit("apple", "red", 12) fruit2 = Fruit("pear", "green", 22) fruit3 = Fruit("banana", "yellow", 32) fruits = [fruit3, fruit2, fruit1]

La lista simple de fruits será mucho más fácil, menos confusa y mejor conservada.

Algunos ejemplos de uso:

Todas las salidas a continuación son el resultado después de ejecutar el fragmento de código dado seguido por:

for fruit in fruits: print fruit

Lista sin clasificar:

Muestra:

Name: banana, Color: yellow, Quantity: 32 Name: pear, Color: green, Quantity: 22 Name: apple, Color: red, Quantity: 12

Ordenado alfabéticamente por nombre:

fruits.sort(key=lambda x: x.name.lower())

Muestra:

Name: apple, Color: red, Quantity: 12 Name: banana, Color: yellow, Quantity: 32 Name: pear, Color: green, Quantity: 22

Ordenado por cantidad:

fruits.sort(key=lambda x: x.quantity)

Muestra:

Name: apple, Color: red, Quantity: 12 Name: pear, Color: green, Quantity: 22 Name: banana, Color: yellow, Quantity: 32

Donde color == rojo:

red_fruit = filter(lambda f: f.color == "red", fruits)

Muestra:

Name: apple, Color: red, Quantity: 12


Un diccionario probablemente no es lo que deberías usar en este caso. Una biblioteca con más funciones sería una mejor alternativa. Probablemente una base de datos real. Lo 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 esta ruta, puede hacerlo con los atributos adicionales en la clave o el valor. Sin embargo, un diccionario no puede ser la clave para otro diccionario, pero sí una tupla. Los documentos explican lo que está permitido. Debe ser un objeto inmutable, que incluye cadenas, números y tuplas que contienen solo cadenas y números (y más tuplas que contienen solo esos tipos recursivamente ...).

Podría hacer su primer ejemplo con d = {(''apple'', ''red'') : 4} , pero será muy difícil consultar lo que desea. Deberías hacer algo como esto:

#find all apples apples = [d[key] for key in d.keys() if key[0] == ''apple''] #find all red items red = [d[key] for key in d.keys() if key[1] == ''red''] #the red apple redapples = d[(''apple'', ''red'')]