2017-03-11 2 views
0

Ich habe zwei Liste der dicts sagen:in einem

rds_detail:

[ { 'rds_name': u'emsclassicldap', 'rds_type': u'db.m3.medium'}, 
    { 'rds_name': u'fra01-devops-KPX', 'rds_type': u'db.t2.medium'}, 
    { 'rds_name': u'prodreplica', 'rds_type': u'db.t2.medium'} 
] 

cloudwatch_detail:

[ { 'alarm_name': u'emsclassicldap_db_connections', 'alarm_threshold': 380.0}, 
    { 'alarm_name': u'fra01-devops-KPX_db_connection', 
     'alarm_threshold': 266.0}, 
    { 'alarm_name': u'prodreplica_db_connections', 
     'alarm_threshold': 266.0}, 
] 

Die alarm_name hat tatsächlich rds_name als Teilkette; I müssen diese beiden Listen in einer solchen Situation kombinieren, damit das Endergebnis wie folgt aussieht:

[ 
    { 'rds_name': u'emsclassicldap', 'rds_type': u'db.m3.medium','alarm_name': u'classicldap_db_connections', 'alarm_threshold': 380.0} 
    . 
    . 
    So on 
    . 
    . 
] 

Ich schreibe eine einfache def zu kombinieren:

def combine_rds_cloudwatch(rds_detail,cloudwatch_detail): 
    print rds_detail,cloudwatch_detail 

    for rds in rds_detail: 
     for alarm in cloudwatch_detail: 
      if ???????????? 

nicht sicher, wie dies zu tun

+0

ich über die Liste iterieren würde, den Wert von 'rds_name' erhalten und verwenden' in list2 [index] [ 'alarm_name '] 'mache ein dict update und füge es in eine neue Liste ein – Bobby

+1

Mit dem' in'-Operator kannst du nach Teilstrings suchen, z 'if rds ['rds_name'] in Alarm ['Alarm_Name']:' für diese if-Anweisung. Sie möchten eine neue Liste von Wörterbüchern zurückgeben. Versuchen Sie, mit 'dict.items()' zu experimentieren, wodurch Sie die Einträge eines Wörterbuchs iterieren können. – Archimaredes

Antwort

2

Eine generische Methode ..

rds_list = [{'rds_name': u'emsclassicldap', 'rds_type': u'db.m3.medium'}, 
      {'rds_name': u'fra01-devops-KPX', 'rds_type': u'db.t2.medium'}, 
      {'rds_name': u'goldenprodreplica', 'rds_type': u'db.t2.medium'} 
      ] 

cloudwatch_list = [{'alarm_name': u'emsclassicldap_db_connections', 'alarm_threshold': 380.0}, 
        {'alarm_name': u'fra01-devops-KPX_db_connection', 'alarm_threshold': 266.0}, 
        {'alarm_name': u'goldenprodreplica_db_connections', 'alarm_threshold': 266.0}, 
        ] 


def merge_two_dicts(x, y): 
    """Given two dicts, merge them into a new dict as a shallow copy. 
     More info here http://stackoverflow.com/questions/38987/how-to-merge-two-python-dictionaries-in-a-single-expression?rq=1 
    """ 
    z = x.copy() 
    z.update(y) 
    return z 


def combine_list(prefix_key_list, prefix_key, keys_list, key): 
    combined_list = [] 

    for short in prefix_key_list: 
     for long in keys_list: 
      if long[key].startswith(short[prefix_key]): 
       result = merge_two_dicts(long, short) 
       combined_list.append(result) 

    return combined_list 


print(combine_list(rds_list, 'rds_name', cloudwatch_list, 'alarm_name')) 
+0

ja .. schön,! sah es jetzt –

2

Und dict(one_dict, **other_dict) werden Sie ein anderes Wörterbuch mit Elementen aus beiden Wörterbücher geben:

>>> d1 = {'a': 1, 'b': 2} 
>>> d2 = {'c': 3, 'd': 4} 
>>> dict(d1, **d2) # => dict({'a':1,'b':2}, c=3, d=4) 
{'a': 1, 'c': 3, 'b': 2, 'd': 4} 

Sie können (zwei für Klausel) verwenden, um Produkte herzustellen und sie mit if c zu filtern. C lause:

def combine_rds_cloudwatch(rds_detail,cloudwatch_detail): 
    return [dict(rds, **alarm) for rds in rds_detail 
           for alarm in cloudwatch_detail 
           if rds['rds_name'] in alarm['alarm_name']] 
          # OR if alarm['alarm_name'].startswith(rds['rds_name']) 
+0

aber überprüft es den Zustand, den ich erwähnte? rds_name ist ein Teilstring in alarm_name, es muss zuerst –

+0

@NishantSingh, das habe ich verpasst. Ich habe die Antwort entsprechend aktualisiert. – falsetru

+0

Ich verstehe, können Sie nur öffnen Sie die Liste Verständnis (ich muss es verstehen, noch neu hier) –

0

Sie startswith verwenden können, um zu überprüfen, ob eine Zeichenkette mit einem anderen beginnt:

from copy import deepcopy 
result = [] 
for rds in rds_detail: 
    temp = deepcopy(rds) 
    for cw in cloudwatch_detail: 
     # replace the condition with rds['rds_name'] in cw['alarm_name'] if the condition 
     # is substring 
     if cw['alarm_name'].startswith(rds['rds_name']): 
      temp.update(cw) 
    result.append(temp) 

result 
#[{'alarm_name': 'emsclassicldap_db_connections', 
# 'alarm_threshold': 380.0, 
# 'rds_name': 'emsclassicldap', 
# 'rds_type': 'db.m3.medium'}, 
# {'alarm_name': 'fra01-devops-KPX_db_connection', 
# 'alarm_threshold': 266.0, 
# 'rds_name': 'fra01-devops-KPX', 
# 'rds_type': 'db.t2.medium'}, 
# {'alarm_name': 'prodreplica_db_connections', 
# 'alarm_threshold': 266.0, 
# 'rds_name': 'prodreplica', 
# 'rds_type': 'db.t2.medium'}] 
+0

Dies wird in der CW aktualisiert? Ich brauche eine separate Liste, die zurückgegeben werden soll. Also sollte ich einfach eine neue Liste über der for-Schleife öffnen und anhängen? –

2

Diese

from pprint import pprint 

pprint([dict(y.items() + next(x.items() for x in rds_detail if x['rds_name'] in y['alarm_name'])) for y in cloudwatch_detail]) 

Geben Sie

[{'alarm_name': u'emsclassicldap_db_connections', 
    'alarm_threshold': 380.0, 
    'rds_name': u'emsclassicldap', 
    'rds_type': u'db.m3.medium'}, 
{'alarm_name': u'fra01-devops-KPX_db_connection', 
    'alarm_threshold': 266.0, 
    'rds_name': u'fra01-devops-KPX', 
    'rds_type': u'db.t2.medium'}, 
{'alarm_name': u'prodreplica_db_connections', 
    'alarm_threshold': 266.0, 
    'rds_name': u'prodreplica', 
    'rds_type': u'db.t2.medium'}] 

Ist es die richtige Ausgabe?

Wenn Sie die Reihenfolge der Elemente in beiden Listen kennen, können Sie auch tun, nur

pprint([dict(x.items() + y.items()) for x, y in zip(rds_detail, cloudwatch_detail)]) 
Verwandte Themen