Ich greife auf eine Liste von Wörterbuchelementen list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}] zu und versuche, jeden Eintrag mithilfe einer Funktion add_entries bedingt an eine andere Liste article_list anzuhängen.

Meine gewünschte Ausgabe

article_list = [{x:1a, y:1b, z:1c}, {x:2a}, {x:3a, y:3b, z:3c}]

Mein Code:


def add_entries(list_of_dict):
   keys = ['x','y','z']
   #defining a temporary dictionary here
   my_dict = dict.fromkeys(keys,0)
   entry_keys = ['ka','kb','kc']

   my_list = []

   for item in list_of_dict:
    # conditionally append the entries into the temporary dictionary maintaining desired key names
        my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
        my_list.append(my_dict)

   return my_list



if __name__ == "__main__":
   list_of_dict = [{'ka':'1a', 'kb':'1b', 'kc':'1c'},{'ka':'2a'},{'ka':'3a', 'kb':'3b', 'kc':'3c'}]
   article_list = []
   returned_list = add_entries(list_of_dict)
   article_list.extend(returned_list)

Meine Ausgabe

article_list = [{x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}, {x:3a, y:3b, z:3c}]
0
sheth7 7 Feb. 2020 im 20:05

3 Antworten

Beste Antwort

Was ist los

my_list.append(my_dict) hängt eine Referenz an das my_dict Objekt an my_list an. Daher befindet sich am Ende der for - Schleife in Ihrem Beispiel my_list eine Liste von Verweisen auf genau dasselbe Wörterbuch im Speicher.

Sie können dies mit der Funktion id selbst sehen. id, zumindest in CPython, gibt Ihnen im Grunde die Speicheradresse eines Objekts. Wenn Sie tun

article_list.extend(returned_list)
print([id(d) for d in article_list])

Sie erhalten eine Liste identischer Speicheradressen. Auf meiner Maschine bekomme ich

[139920570625792, 139920570625792, 139920570625792]

Die Folge ist, dass die Aktualisierung des Wörterbuchs "alle Wörterbücher" in Ihrer Liste betrifft. (Zitate, weil Ihre Liste wirklich nicht mehrere Wörterbücher enthält, sondern nur ein Vielfaches des exakt gleichen). Am Ende ist also nur der letzte Aktualisierungsvorgang für Sie sichtbar.

Eine gute Diskussion zu Referenzen und Objekten in Python finden Sie in dieser Antwort https://stackoverflow.com/a/30340596/8791491

Das Update

Wenn Sie die Definition von my_dict in die for -Schleife verschieben, erhalten Sie für jedes Element von my_list ein neues, separates Wörterbuch. Jetzt wirkt sich der Aktualisierungsvorgang nicht auf die anderen Wörterbücher in der Liste aus, und my_list ist eine Liste mit Verweisen auf mehrere verschiedene Wörterbücher.

def add_entries(list_of_dict):
    keys = ['x','y','z']
    entry_keys = ['ka','kb','kc']

    my_list = []

    for item in list_of_dict:
        #defining a new dictionary here
        my_dict = dict.fromkeys(keys,0)

        # conditionally append the entries into the temporary dictionary maintaining desired key names
        my_dict.update({a: item[b] for a,b in zip(keys, entry_keys) if b in item})
        my_list.append(my_dict)

    return my_list
1
L.Grozinger 7 Feb. 2020 im 17:54

Versuche dies:

list_new_d=[]
for d in list_of_dict:
  new_d={}

  for k,v in d.items():
    if k == 'ka':
      new_d['x'] = v

    if k == 'kb':
      new_d['y'] = v

    if k == 'kc':
      new_d['z'] = v
  list_new_d.append(new_d)

0
Shubham Shaswat 7 Feb. 2020 im 17:15

Sie können dies verwenden.

keys=['x','y','z']
res=[{k1:d[k]} for d in list_of_dict for k,k1 in zip(d,keys)]

Ausgabe

[{'x': '1a'},
 {'y': '1b'},
 {'z': '1c'},
 {'x': '2a'},
 {'x': '3a'},
 {'y': '3b'},
 {'z': '3c'}]
1
Ch3steR 7 Feb. 2020 im 17:14