2016-08-25 1 views
0
UG=[ 
    {"group_member":"myGroup1","user_name":"tom"}, 
    {"group_member":"myGroup2","user_name":"wilson"}, 
    {"group_member":"myGroup1","user_name":"kevin"}, 
    {"group_member":"myGroup2","user_name":"donna"}, 
    {"group_member":"myGroup3","user_name":"john"}, 
    {"group_member":"myGroup1","user_name":"steve"}, 
    {"group_member":"myGroup2","user_name":"jose"}, 
    {"group_member":"myGroup3","user_name":"jags"}] 
PG=[ 
    {"group_member":"myGroup1","device_name":"device1"}, 
    {"group_member":"myGroup1","device_name":"device2"}, 
    {"group_member":"myGroup2","device_name":"device1"}, 
    {"group_member":"myGroup1","device_name":"device2"}, 
    {"group_member":"myGroup1","device_name":"device3"}, 
    {"group_member":"myGroup3","device_name":"device1"}] 
DG=[ 
    {"device_name":"device1","server":"server1"}, 
    {"device_name":"device2","server":"server2"}, 
    {"device_name":"device3","server":"server3"}, 
    {"device_name":"device4","server":"server4"}, 
    {"device_name":"device5","server":"server5"}, 
    {"device_name":"device6","server":"server6"} 
    ] 

Мне нужно сравнить списки и подготовить список словаря со следующим условиемлучший способ сделать Dict понимание

UG[i]['group_member'] == PG[j]['group_member'] && PG[j]['device_name'] == UG[k]['device_name'] 

вот моя реализация

# output array 
output=[] 
for i in DG: 
    for j in PG: 
     if i["device_name"] == j["device_name"]: 
      for k in UG: 
       if k["group_member"] == j["group_member"]: 
        output.append({"user_name":k["user_name"],"group_member":k["group_member"],"device_name":j["device_name"],"server":i["server"]}) 

for m in output: 
    print m 

требуемый выход == ==========

[ 
    {'server': 'server1', 'user_name': 'tom', 'group_member': 'myGroup1', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'kevin', 'group_member': 'myGroup1', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'steve', 'group_member': 'myGroup1', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'wilson', 'group_member': 'myGroup2', 'device_name': 'device1'} 
    {'server': 'server1', 'user_name': 'donna', 'group_member': 'myGroup2', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'jose', 'group_member': 'myGroup2', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'john', 'group_member': 'myGroup3', 'device_name': 'device1'}, 
    {'server': 'server1', 'user_name': 'jags', 'group_member': 'myGroup3', 'device_name': 'device1'}, 
    {'server': 'server2', 'user_name': 'tom', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server2', 'user_name': 'kevin', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server2', 'user_name': 'steve', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server2', 'user_name': 'tom', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server2', 'user_name': 'kevin', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server2', 'user_name': 'steve', 'group_member': 'myGroup1', 'device_name': 'device2'}, 
    {'server': 'server3', 'user_name':'tom', 'group_member': 'myGroup1', 'device_name': 'device3'}, 
    {'server': 'server3', 'user_name': 'kevin', 'group_member': 'myGroup1', 'device_name': 'device3'}, 
    {'server': 'server3', 'user_name': 'steve', 'group_member': 'myGroup1', 'device_name': 'device3'} 
] 

Как я могу улучшить свою реализацию?

ответ

2

Да, это может быть сделано с использованием понимания списка. Но давайте сначала создать функциональную функцию обновления ДИКТ, так как dict «s метод обновления не возвращает новый Dict (но, скорее, обновляет текущий):

def updt(d1, d2): 
    d3 = d1.copy() 
    d3.update(d2) 
    return d3 

А теперь давайте дикое со списком понимания:

dictlist = [updt(updt(ug, pg), dg) for ug in UG for pg in PG for dg in DG if ug['group_member'] == pg['group_member'] and pg['device_name'] == dg['device_name']] 

Вот результат:

for d in dictlist: 
    print(d)    

И у вас есть:


{'user_name': 'tom', 'server': 'server1', 'group_member': 'myGroup1', 'device_name': 'device1'} 
{'user_name': 'tom', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'tom', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'tom', 'server': 'server3', 'group_member': 'myGroup1', 'device_name': 'device3'} 
{'user_name': 'wilson', 'server': 'server1', 'group_member': 'myGroup2', 'device_name': 'device1'} 
{'user_name': 'kevin', 'server': 'server1', 'group_member': 'myGroup1', 'device_name': 'device1'} 
{'user_name': 'kevin', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'kevin', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'kevin', 'server': 'server3', 'group_member': 'myGroup1', 'device_name': 'device3'} 
{'user_name': 'donna', 'server': 'server1', 'group_member': 'myGroup2', 'device_name': 'device1'} 
{'user_name': 'john', 'server': 'server1', 'group_member': 'myGroup3', 'device_name': 'device1'} 
{'user_name': 'steve', 'server': 'server1', 'group_member': 'myGroup1', 'device_name': 'device1'} 
{'user_name': 'steve', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'steve', 'server': 'server2', 'group_member': 'myGroup1', 'device_name': 'device2'} 
{'user_name': 'steve', 'server': 'server3', 'group_member': 'myGroup1', 'device_name': 'device3'} 
{'user_name': 'jose', 'server': 'server1', 'group_member': 'myGroup2', 'device_name': 'device1'} 
{'user_name': 'jags', 'server': 'server1', 'group_member': 'myGroup3', 'device_name': 'device1'} 

который кажется, что вы хотите, хотя в другом порядке.

+1

Я предлагаю использовать 'itertools.product' для улучшения читаемости далее:' [... для уг, пг, дг в продукте (UG, PG, DG), если ...] '. –

+0

@ IljaEverilä, как и идея, пробовал, но он остается той же длиной выражения. Сравните: 'для ug в UG для pg в PG для dg в DG' для' для ug, pg, dg в произведении (UG, PG, DG) '. И мне даже нравится использовать имя модуля, поэтому оно становится 'itertools.product' ... –

+0

Лично мне просто легче рассуждать о одном декартовом вызове продукта, а не повторять за ... для ... для .. .конструкции. YMMV :) –

1

Если у вас есть тысячи записей здесь генератор

from itertools import product 

def produce(): 
    for dg, pg, ug in product(DG, PG, UG): 
     if pg['device_name'] == dg['device_name'] and ug['group_member'] == pg['group_member']: 
      item = dg.copy() 
      item.update(pg) 
      item.update(ug) 
      yield item