2013-05-12 5 views
0

У меня есть два списка, в которых я храню информацию о немногих знаменитостях и другой список, в котором храню информацию о наградах, относящуюся к этим актерам.Добавление списка dicts в качестве элемента из другого списка (Python)

Проблема, которую пытаюсь решить, состоит в объединении этих двух списков в один, где информация о наградах становится атрибутом, который по существу является списком наград. И да, этого легко достичь.

for actor in actor_info: 
    for award in award_list: 
     if actor['personid'] == award['personid']: 
      if not actor.get('awards', False): 
       actor.update({'awards':[]}) 
      actor['awards'].append(award) 

Но если вы соблюдаете код выше, он перебирает len(actor_info) * len(award_list) раз, что не является элегантным решением. Есть ли другая перспектива для этой проблемы, где циклы выполнения намного меньше.


Примечание:

Чтобы объяснить эту проблему гораздо более четко, я описал ниже структуры данных, я использую. Каждый элемент в списке actor_info и award_info по существу является словарем.

actor_info = [] 

d = {} 
d['personid'] = 1210 
d['firstname'] = 'Robert , Jr' 
d['lastname'] = 'Downey' 
d['birthplace'] = 'manhattan, NY' 

d1 = {} 
d1['personid'] = 2842 
d1['firstname'] = 'Brad' 
d1['lastname'] = 'Pitt' 
d1['birthplace'] = 'Shawnee, OK' 

d2 = {} 
d2['personid'] = 361 
d2['fname'] = 'Cate' 
d2['lname'] = 'Blanchett' 
d2['birthplace'] = 'Melbournce, Victoria' 

d3 = {} 
d3['personid'] = 261 
d3['fname'] = 'Meg' 
d3['lname'] = 'Ryan' 
d3['birthplace'] = 'Melbournce, Victoria' 

actor_info.append(d) 
actor_info.append(d1) 
actor_info.append(d2) 
actor_info.append(d3) 

информация Награда:

k = {} 
k['year'] = '1992' 
k['won'] = 'NO' 
k['category'] = 'Best Actor' 
k['name'] = 'Academy Award' 
k['movie'] = 'Chaplin' 
k['personid'] = 1210 

k1 = {} 
k1['year'] = '2008' 
k1['won'] = 'NO' 
k1['category'] = 'Best Actor' 
k1['name'] = 'Academy Award' 
k1['movie'] = 'Tropic thunder' 
k1['personid'] = 1210 

k2 = {} 
k2['year'] = '2008' 
k2['won'] = 'NO' 
k2['category'] = 'Best Actor' 
k2['name'] = 'Academy Award' 
k2['movie'] = 'The Curious Case of Benjamin Button' 
k2['personid'] = 2842 

k3 = {} 
k3['year'] = '1989' 
k3['won'] = 'yes' 
k3['category'] = 'Best supporting Actress' 
k3['name'] = 'Academy award' 
k2['movie'] = 'Aviator' 
k3['personid'] = 361 

award_list = [] 
award_list.append(k) 
award_list.append(k1) 
award_list.append(k2) 
award_list.append(k3) 

ответ

1

Во-первых, вы должны перейти из словарей collections.namedtuple, что позволяет получить доступ к данным, как простые атрибуты.

В любом случае, вы можете избежать квадратичной итерации, сделав таблицу поиска перед рукой.

idToActor = {a['personid']:a for a in actor_info} 

for award in award_list: 
    actor = idToActor[award['personid']] 
    actor.setdefault('awards',[]).append(award) 
+0

Благодарим вас за предложение collection.namedtuple, сейчас оно будет реализовано. – Chaitanya

0

Во-первых, я бы реструктуризировать, как хранить actor_info на что-то вроде этого:

actor_info['personid'] = {'fname':'Cate',...,"awards":list()} 

С текущего кода это может быть достичь с помощью следующего кода:

actor_info = {} 
for actor in [d,d1,d2,d3]: 
    actor_info[actor['personid']] = dict([(k,v) for (k,v) in actor.items() if k != 'personid']) 
    actor_info[actor['personid']]['awards'] = list() 

Теперь, чтобы дать каждый актер - их награда (-ы)

for award in award_list: 
    if actor_info.has_key(award['personid']): #if an actor exists with the same personID 
     actor_info[award['personid']]['awards'].append(award) #append the award to their award list 

Это будет работать примерно в течение O (N).

Смежные вопросы