2013-09-21 16 views
25

Sto provando a definire una procedura, involved(courses, person), che prende come input una struttura di corsi e una persona e restituisce un dizionario che descrive tutti i corsi che la persona è coinvolti inTipoError: gli indici stringa devono essere interi, non str // lavorare con dict

Ecco il mio involved(courses, person) funzione:.

def involved(courses, person): 
    for time1 in courses: 
     for course in courses[time1]: 
      for info in time1[course]: 
       print info 

Ecco il mio dizionario:

courses = { 
    'feb2012': { 'cs101': {'name': 'Building a Search Engine', 
          'teacher': 'Dave', 
          'assistant': 'Peter C.'}, 
       'cs373': {'name': 'Programming a Robotic Car', 
          'teacher': 'Sebastian', 
          'assistant': 'Andy'}}, 
    'apr2012': { 'cs101': {'name': 'Building a Search Engine', 
          'teacher': 'Dave', 
          'assistant': 'Sarah'}, 
       'cs212': {'name': 'The Design of Computer Programs', 
          'teacher': 'Peter N.', 
          'assistant': 'Andy', 
          'prereq': 'cs101'}, 
       'cs253': 
       {'name': 'Web Application Engineering - Building a Blog', 
          'teacher': 'Steve', 
          'prereq': 'cs101'}, 
       'cs262': 
       {'name': 'Programming Languages - Building a Web Browser', 
          'teacher': 'Wes', 
          'assistant': 'Peter C.', 
          'prereq': 'cs101'}, 
       'cs373': {'name': 'Programming a Robotic Car', 
          'teacher': 'Sebastian'}, 
       'cs387': {'name': 'Applied Cryptography', 
          'teacher': 'Dave'}}, 
    'jan2044': { 'cs001': {'name': 'Building a Quantum Holodeck', 
          'teacher': 'Dorina'}, 
       'cs003': {'name': 'Programming a Robotic Robotics Teacher', 
          'teacher': 'Jasper'}, 
        } 
    } 

Quando ho' sto cercando di testare il mio codice:

>>>print involved(courses, 'Dave') 

Python mi danno un errore:

for info in time1[course]: 
TypeError: string indices must be integers, not str 

Come posso rimediare?

Grazie.

risposta

29

time1 è la chiave del dizionario più esterno, ad esempio feb2012. Quindi stai cercando di indicizzare la stringa, ma puoi farlo solo con numeri interi. Penso che quello che volevi fosse:

for info in courses[time1][course]: 

Mentre passi attraverso ciascun dizionario, devi aggiungere un altro nido.

5

In realtà penso che più approccio generale al ciclo attraverso dizionario è quello di utilizzare iteritems():

# get tuples of term, courses 
for term, term_courses in courses.iteritems(): 
    # get tuples of course number, info 
    for course, info in term_courses.iteritems(): 
     # loop through info 
     for k, v in info.iteritems(): 
      print k, v 

uscita:

assistant Peter C. 
prereq cs101 
... 
name Programming a Robotic Car 
teacher Sebastian 

Oppure, come Matthias accennato nei commenti, se non è necessario chiavi, si può semplicemente utilizzare itervalues():

for term_courses in courses.itervalues(): 
    for info in term_courses.itervalues(): 
     for k, v in info.iteritems(): 
      print k, v 
+0

Quando non è necessaria la chiave, è possibile utilizzare [itervalues] (http://docs.python.org/2/library/stdtypes.html#dict.itervalues). – Matthias

+0

Sì, grazie per l'aggiunta, non so se OP vuole usare le chiavi, ma dovrei notare che –

0

Vedo che stai cercando un'implementazione del problema più che risolvere quell'errore. Ecco una possibile soluzione:

from itertools import chain 

def involved(courses, person): 
    courses_info = chain.from_iterable(x.values() for x in courses.values()) 
    return filter(lambda x: x['teacher'] == person, courses_info) 

print involved(courses, 'Dave') 

La prima cosa che faccio è sempre la lista dei corsi e poi filtrare in base al nome del docente.

+0

in realtà è possibile fare senza catena - '[i per x in courses.values ​​() per i in x.values() se io ["insegnante"] == persona] ' –

+0

Sì, hai ragione. Grazie per il suggerimento – moliware

Problemi correlati