unzippen eines Dictionaries als Klassenattribut: ValueError: too many values to unpack

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
stillsen
User
Beiträge: 6
Registriert: Mittwoch 20. März 2019, 15:01

Hi,
ich verstehe nicht wieso das unzippen meines dictionaries fehlschlaegt.
Waere spitze wenn Ihr mir helfen koenntet das zu verstehen.

Es gibt eine Klasse data_handler mit einem Attribut samples_per_class, was ein dictionary ist.

Code: Alles auswählen

data_handler.samples_per_class = <class 'dict'>: {'Basidiomycota': 5, 'Ascomycota': 190, 'nan': 0, 'Mortierellomycota': 10}
Jedoch kann ich das dict nicht unzippen:

Code: Alles auswählen

x, y = zip(*data_handler.samples_per_class) = ValueError: too many values to unpack (expected 2)
Und direkt auf die values oder keys zugreifen produziert:

Code: Alles auswählen

x = data_handler.samples_per_class.values() = None
y =  = data_handler.samples_per_class.keys() = None
Vielen Dank!
Benutzeravatar
__blackjack__
User
Beiträge: 14040
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@stillsen: Wenn `samples_per_class` tatsächlich den Typ `dict` hat, dann sind `x` und `y` im zweiten Beispiel *nicht* an `None` gebunden, sondern an die Werte und die Schlüssel. Je nach Python-Version entweder an Listen, oder an ”view”-Objekte.

Schaust Du hier (ab [4] um zu zeigen was der `zip()`-Versuch als Ergebnis liefert):

Code: Alles auswählen

In [1]: samples_per_class = {'Basidiomycota': 5, 'Ascomycota': 190, 'nan': 0, 'Mortierellomycota': 10}

In [2]: samples_per_class.keys()
Out[2]: dict_keys(['Basidiomycota', 'Ascomycota', 'nan', 'Mortierellomycota'])

In [3]: samples_per_class.values()
Out[3]: dict_values([5, 190, 0, 10])

In [4]: list(samples_per_class)
Out[4]: ['Basidiomycota', 'Ascomycota', 'nan', 'Mortierellomycota']

In [5]: list(zip(*list(samples_per_class)))
Out[5]: [('B', 'A', 'n', 'M'), ('a', 's', 'a', 'o'), ('s', 'c', 'n', 'r')]
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
stillsen
User
Beiträge: 6
Registriert: Mittwoch 20. März 2019, 15:01

danke fuer deine Antwort!
Ich benutze Python 3.5.3

Wenn ich dein [4] und [5] ausfuehre bekomme ich ganz aehnliche Ergebnisse (die unterschiedlichen (Key, Value) Inhalte in meiner Ausfuehrung kommen daher, weil ich gerade was am Code geschraubt habe):

Code: Alles auswählen

data_handler.samples_per_class = <class 'dict'>: {'Mortierellomycota': 11, 'Ascomycota': 189, 'nan': 0, 'Basidiomycota': 5}
list(data_handler.samples_per_class) = <class 'list'>: ['Mortierellomycota', 'Ascomycota', 'nan', 'Basidiomycota']
list(zip(*list(data_handler.samples_per_class))) = <class 'list'>: [('M', 'A', 'n', 'B'), ('o', 's', 'a', 'a'), ('r', 'c', 'n', 's')]
Ich glaube ich habe verpasst zu sagen was ich eigentlich will.
Ich hatte mir erhofft, dass

Code: Alles auswählen

x, y = zip(*data_handler.samples_per_class)
mir

Code: Alles auswählen

x= ['Mortierellomycota', 'Ascomycota', 'nan', 'Basidiomycota']
y= [11, 189, 0, 5]
liefert.
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@stillsen: Warum so kompliziert? Warum nicht über den Weg, den Python für sowas vorgesehen hat?

Code: Alles auswählen

>>> d = {'Mortierellomycota': 11, 'Ascomycota': 189, 'nan': 0, 'Basidiomycota': 5}
>>> d
{'Mortierellomycota': 11, 'Ascomycota': 189, 'nan': 0, 'Basidiomycota': 5}
>>> x = list(d.keys())
>>> y = list(d.values())
>>> x
['Mortierellomycota', 'Ascomycota', 'nan', 'Basidiomycota']
>>> y
[11, 189, 0, 5]
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

warum sollte zip sowas machen?
wie wäre es hiermit:

Code: Alles auswählen

x,y = data_handler.samples_per_class.keys(), data_handler.samples_per_class.values()
Arrgh, pillmuncher was faster.... :-)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
stillsen
User
Beiträge: 6
Registriert: Mittwoch 20. März 2019, 15:01

sehr gute Frage!
:)

Code: Alles auswählen

x = list(d.keys())
y = list(d.values())
gibt mir genau was ich will.
dankoe!
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@pillmuncher: weil das voraussetzt, dass die Reihenfolge von keys und values die selbe ist.
Sonst ist die Lösung:

Code: Alles auswählen

x, y = zip(*data_handler.samples_per_class.items())
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Sirius3: Stimmt. Allerdings ist seit Py3.7 garantiert, dass die Reihenfolge gleich ist. Siehe https://docs.python.org/3/library/stdty ... dict-views
In specifications, Murphy's Law supersedes Ohm's.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

pillmuncher hat geschrieben: Freitag 29. März 2019, 21:14 @Sirius3: Stimmt. Allerdings ist seit Py3.7 garantiert, dass die Reihenfolge gleich ist. Siehe https://docs.python.org/3/library/stdty ... dict-views
Nein, dass die Reihenfolge con keys() und values() die gleiche ist, das ist schon länger garantiert: https://docs.python.org/release/1.5.2p2 ... pping.html
Neu ist in 3.7, dass die Reihenfolge auch noch der Reihenfolge des Einfügens ins dictionary entspricht. Die war vorher explizit relativ beliebig (wenn auch nicht zufällig). Geändert hat sie sich aber nur, wenn etwas eingefügt oder gelöscht wurde.
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@bords0: Danke. Seit ich kaum mehr in Python programmiere, vergesse ich scheinbar alles, was ich schon mal wusste.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Sirius3 hat geschrieben: Freitag 29. März 2019, 20:50 Sonst ist die Lösung:

Code: Alles auswählen

x, y = zip(*data_handler.samples_per_class.items())
@Sirius3 Ich möchte zu dieser genialen Lösung nur anmerken, dass x und y dann Tuple sind, keine Listen.
Sollte letzteres, warum auch immer, nötig sein, ist der Weg über list(d.keys()) etc. schneller.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten