2011-04-03 7 views
5

Esto es tarea, así que no espero la respuesta, solo un punto en la dirección correcta.¿Encontrar un elemento de una lista cuando la lista está en un diccionario?

en Python I tienen un diccionario que es así:

{'bike101': ('Road Bike', 
      [('WH139', 2), 
       ('TR102', 2), 
       ('TU177', 2), 
       ('FR101', 1), 
       ('FB101', 1), 
       ('BB101', 1), 
       ('GS101', 1)]), 
'bike201': ('Mountain Bike', 
      [('WH239', 2), 
       ('TR202', 2), 
       ('TU277', 2), 
       ('FR201', 1), 
       ('FB201', 1), 
       ('BB201', 1), 
       ('GS201', 1)]), 
'bike301': ('Racing Bike', 
      [('WH339', 2), 
       ('TR302', 2), 
       ('TU377', 2), 
       ('FR301', 1), 
       ('FB301', 1), 
       ('BB301', 1), 
       ('GS301', 1)])} 

Por ejemplo 'Racing Bike' es el nombre del producto y la lista de pares es (parte, cantidad necesaria), respectivamente.

Tengo que escribir una función que, dado el diccionario anterior y el nombre del producto como argumento, devolverá la clave y devolverá 'Ninguno' si el nombre del producto no existe.

utilicé:

return [key for key, value in product_dict.iteritems() if list(value)[0] == string] 

Y esto volvió la tecla correcta cuando se probó, pero no sé cómo hacer que vuelva 'ninguno' si el nombre del producto no existe y no estoy seguro de si esta es la mejor manera de hacer esto '.

Solo puedo usar las funciones integradas en Python, ¡cualquier ayuda es muy apreciada!

Respuesta

2

Dado que está pidiendo pistas, no voy a publicar código de trabajo.

Su código es una lista de comprensión, por lo que muestra una lista. Si no hay resultados, la lista estará vacía. Puede vincular la lista a una variable, use len() para verificar su longitud y devuelva None si es 0.

+0

Muchas gracias por su ayuda, ¡solución muy simple pero elegante! – Sean

2

Usar una lista de comprensión tal vez no sea la manera más obvia aquí ya que no está compilando una lista sino buscando un solo artículo. Su código no devuelve la clave sino una lista de tamaño 1 si se encuentra la clave o una lista de tamaño 0 si no existe.

Una forma de utilizar esto para su ventaja es acceder al primer elemento ([0]) de su lista de comprensión. Entonces obtendrá un IndexError si la lista está vacía. Rodee la lista de comprensión con un try/except y devuelva None si se genera IndexError.

1

Una lista de comprensión es para crear una lista; lo que realmente quieres aquí es encontrar datos. Eso sugiere de inmediato un diccionario, pero en esta situación, la forma más sencilla sería usar bucles para simplemente recorrer los datos e intentar hacer coincidir el nombre del producto.

Si lo que necesita hacer este tipo de búsquedas de frecuencia (Entiendo que esto es tarea, pero vamos a suponer que estaba escribiendo esto para el trabajo), entonces será mejor hacer un nuevo diccionario que está enchavetado por el producto nombre directamente. Te voy a mostrar que la solución, lo que probablemente no es la solución requerida por su tarea, pero tal vez puedo encontrar la manera de adaptarlo a la solución más simple el uso de bucles:

# Restructure the dictionary 
def invert_dictionary(input): 
    out={} 
    for bike_number in input.keys():     
     product_name, list_of_parts = input[bike_number] 
     if not out.has_key(product_name): 
      out[product_name]=[]   
     out[product_name].append((bike_number, list_of_parts)) 
    return out 

new_dict = invert_dictionary(d) 
# Returns a list of all bikes that are tagged "Racing Bike" 
print new_dict['Racing Bike'] 

Salida:

[('bike301', [('WH339', 2), ('TR302', 2), ('TU377', 2), ('FR301', 1), ('FB301', 1), ('BB301', 1), ('GS301', 1)])] 

Estudie cómo los bucles en este código recorren los datos. Deberá hacer algo similar para encontrar los datos que necesita en el dict original.

0

En una línea:

product_dict = {'bike301': ('Racing Bike', [('WH339', 2),('TR302', 2), 
              ('TU377', 2),('FR301', 1), 
              ('FB301', 1),('BB301', 1), 
              ('GS301', 1) 
              ] 
          ), 
       'bike201': ('Mountain Bike', [('WH239', 2),('TR202', 2), 
               ('TU277', 2),('FR201', 1), 
               ('FB201', 1),('BB201', 1), 
               ('GS201', 1) 
               ] 
          ), 
       'bike101': ('Road Bike', [('WH139', 2),('TR102', 2), 
              ('TU177', 2),('FR101', 1), 
              ('FB101', 1),('BB101', 1), 
              ('GS101', 1) 
              ] 
          ) 
       } 


print dict((string,k) for k,(name,li) in product_dict.iteritems() if name==string).get(string,None) 

veo ninguna ventaja de tener los elementos de su diccionario bajo la forma number:(name,a_list)

creo que debería ser mejor para definir:

product_dict2 = {('bike301','Racing Bike'):[('WH339', 2),('TR302', 2), 
              ('TU377', 2),('FR301', 1), 
              ('FB301', 1),('BB301', 1), 
              ('GS301', 1) 
              ], 
       ('bike201','Mountain Bike'):[('WH239', 2),('TR202', 2), 
               ('TU277', 2),('FR201', 1), 
               ('FB201', 1),('BB201', 1), 
               ('GS201', 1) 
               ], 
       ('bike101','Road Bike'):[('WH139', 2),('TR102', 2), 
              ('TU177', 2),('FR101', 1), 
              ('FB101', 1),('BB101', 1), 
              ('GS101', 1) 
              ] 
       } 

Entonces para su necesidad, usted escribiría:

print dict((string,numb) for numb,name in product_dict2.iterkeys() if name==string).get(string,None) 
Cuestiones relacionadas