Dictionaries in Liste Trennen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
dart1609
User
Beiträge: 4
Registriert: Dienstag 9. Februar 2021, 13:50

Hi zusammen,

ist mein erster Post hier, aber das ist normal, wenn man sich gerade erst angemeldet hat. :- )

Ich bin ein absoluter Neuling und arbeite mich gerade durch das Bootcamp von Jannis Seemann. Nichts desto trotz möchte ich mit Hilfe von Python einen direkten Bezug zu meiner Arbeit als Network Consultant schaffen. Dafür habe ich eine Woche Schulungsurlaub bekommen und muss anschließend Ergebnisse liefern. Da ich nun mal wieder auf eine Wand gestoßen bin, dachte ich, das ich mir hier vielleicht noch Hilfe suchen kann.

Szenario: Ich bekomme von einer Management Instanz über eine API Schnittstelle alle Geräte innerhalb eines Netzes, bzw einer Organisation in Form von Dictionaries innerhalb einer Liste angezeigt. Die Felder können hier von Dictionary zu Dictionary unterschiedlich sein. Als Beispiel habe ich es einmal stark verkürzt so dargestellt.

geraete = [
{"Hostname":"SW01", "Typ":"Switch", "Modell":"9300", "IP":"10.255.255.1"},
{"Hostname":"SW02", "Typ":"Switch", "Modell":"9200L", "IP":"10.255.255.2"},
{"Hostname":"SW03", "Typ":"Switch", "Modell":"9200", "IP":"10.255.255.3"},
{"Hostname":"SW04", "Typ":"Switch", "Modell":"9200L", "IP":"10.255.255.4"},
{"Hostname":"AP01", "Typ":"Accesspoint", "Modell":"MR46", "IP":"10.255.254.10"},
{"Hostname":"AP02", "Typ":"Accesspoint", "Modell":"MR46", "IP":"10.255.254.11"},
{"Hostname":"AP03", "Typ":"Accesspoint", "Modell":"MR46", "IP":"10.255.254.12"},
{"Hostname":"AP04", "Typ":"Accesspoint", "Modell":"MR33", "IP":"10.255.254.13"},
{"Hostname":"FW01", "Typ":"Firewall", "Modell":"FTD1120", "IP_IN":"10.255.253.254", "IP_OUT":"1.1.1.2"},
]

Meine Frage wäre es jetzt, ob es möglich wäre sich anhand des Typs mehrere Listen mit Dictionaries erstellen zu lassen. Hier im Prinzip Eine Liste Switch, eine Accesspoint und eine Firewall.

Mein Kläglicher Versuch sah bisher so aus.

switches = []
for x in geraete:
if x['Typ'] == "Switch":
switches.append = [x]

Jetzt nehme ich an, das die Variable 'x' nicht alles enthalten kann, macht ja auch Sinn, aber gibt es eine Möglichkeit das um zusetzten, auch wenn man nicht weiss wie viele Elemente in einem Dictionary sind?


Danke schon mal für die Hilfe.

MfG
Sebastian
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@dart1609: Du solltest vernünftige Namen verwenden. `x` ist hier keiner. Der Name sollte dem Leser vermitteln was der Wert bedeutet. In diesem Fall ist das ein `geraet`. Und wie dieser Wert aussieht kann man sich mit `print()` ja anzeigen lassen. So kannst Du Deine Annahme leicht überprüfen.

Ansonsten bringt Dein Versuch eine recht deutliche Ausnahme. Was genau verstehst Du denn an der nicht?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

In einer Liste geraete sind mehere Exemplare von je einem geraet, kein x.
Ich verstehe nicht ganz, wo das Problem ist, dass in den Wörterbüchern verschiedene Schlüssel sind, solange es jeweils einen Schlüssel "Typ" gibt, ist das doch egal.

Einfacher wäre es, ein Wörterbuch mit Listen zu erzeugen:

Code: Alles auswählen

from collections import defaultdict

geraete_nach_typen = defaultdict(list)
for geraet in geraete:
    geraete_nach_typen[geraet["Typ"]].append(geraet)
dart1609
User
Beiträge: 4
Registriert: Dienstag 9. Februar 2021, 13:50

Hi,

danke für die Schnelle Antwort. Wie gesagt bin ich noch unerfahren und habe erst begonnen. Ziel war es drei Listen aus der einen Liste geraete zu erstellen, basierend auf dem Typ.

Mein neuer Versuch hatte geklappt.

import collections

switches = []
accesspoints = []
firewall = []
result_switches = collections.defaultdict(list)
result_accesspoints = collections.defaultdict(list)
result_firewalls = collections.defaultdict(list)

for x in geraete:
if x['Typ'] == "Switch":
result_switches[x['Typ']].append(x)
switches = list(result_switches.values())
elif x['Typ'] == "Accesspoint":
result_accesspoints[x['Typ']].append(x)
accesspoints = list(result_accesspoints.values())
elif x['Typ'] == "Firewall":
result_firewalls[x['Typ']].append(x)
firewall = list(result_firewalls.values())


Jetzt wollte ich aber wissen, ob das auch ohne den import von collections geklappt hätte?
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@dart1609: Ja hätte es denn was Du da mit dem `defaultdict` machst ist absolut unsinnig. Das ist ja gerade dazu da damit Du die Ergebnisse in *einer* Datenstruktur sammeln kannst, aber trotzdem nach Typ getrennt und ohnedas Du Code für jeden Typ schreiben musst. Also entweder *ein* `defaultdict` *oder* drei Listen und ``if``/``elif``-Zweige. Nicht beides zusammen.

Und bei den ``if``/``elif``-Zweigen funktioniert das was Du am Anfang hattest ja schon fast, nur dass Du da eine falsche Zeile hattest, die zu einer recht deutlichen Fehlermeldung führte. Das müsstest Du korrigieren können, wenn Du den Umgang mit Listen gelernt hast. Der wird beispielsweise im Tutorial in der Python-Dokumentation erklärt.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
dart1609
User
Beiträge: 4
Registriert: Dienstag 9. Februar 2021, 13:50

Naja, wie man Listen um eine weiteres Element erweitert hatte ich im Kurs ja verstanden, mit append, aber wenn es sich nicht um ein einzelnes Element, sondern um ein ganzes dictionary handelt konnte ich noch nicht herausfinden. Die Fehlermeldung war immer "AttributeError: 'list' object attribute 'append' is read-only" Konnte aber bisher nichts damit anfangen. Vielleicht ergibt sich das ja im laufe des Kurses noch, ist ja erst Tag zwei.
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@dart1609: Du benutzt `append()` dort nicht wie Du das im Kurs gelernt hast sondern irgendwie geraten. Und Du willst die Liste ja auch nur um ein einziges Element erweitern. Dieses einzelne Element ist ein Dictionary. Da ist nichts magisches dran oder irgendwie anders als wenn man beispielsweise eine Zahl an eine Liste anhängen würde. Mit ``some_list.append(some_value)`` wird ein beliebiger Wert an eine Liste angehängt. Unabhängig davon was das für ein Wert ist und welchen Typ der hat.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
dart1609
User
Beiträge: 4
Registriert: Dienstag 9. Februar 2021, 13:50

Ah danke für den Hinweis. Tatsächlich benutze ich append da falsch. Geraten war es nicht, war mir sicher und hatte es auch so aufgeschrieben. Tatsächlich habe ich es mir dann noch mal angeschaut.
Antworten