Seite 1 von 1

unpack list of wrong size

Verfasst: Donnerstag 24. März 2005, 15:29
von hehejo

Code: Alles auswählen

>>> a = ["ui", "ua", "uu"]
>>> b = ["1", "2", "3"]
>>> for i , j in a,b:
	print i, j

	

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in -toplevel-
    for i , j in a,b:
ValueError: unpack list of wrong size
>>> 
Warum geht denn das nicht? a und b haben doch die gleiche Länge?
Ich erwartete eine Ausgabe wie diese:

Code: Alles auswählen

ui 1
ua 2
uu 3

Verfasst: Donnerstag 24. März 2005, 15:36
von mawe
Hi!

Entweder so:

Code: Alles auswählen

>>> for i,j in zip(a,b): print i,j
ui 1
ua 2
uu 3
>>> print zip(a,b) # zur Erklärung
[('ui', '1'), ('ua', '2'), ('uu', '3')]
oder so

Code: Alles auswählen

>>> for i in range(len(a)): print a[i], b[i]
ui 1
ua 2
uu 3
Gruß, mawe

Verfasst: Donnerstag 24. März 2005, 16:36
von Leonidas
Ich hätte noch was vorzuschlagen:

Code: Alles auswählen

for num, wort in enumerate(a):
    print wort, num

Verfasst: Donnerstag 24. März 2005, 17:01
von mawe
Hi Leonidas!

Das macht aber ganz was anderes :wink:

Code: Alles auswählen

>>> for num, wort in enumerate(a): print wort, num
ui 0
ua 1
uu 2
Das 2. Array fühlt sich jetzt sicher ziemlich vernachlässigt. Armes Array :cry:

Gruß, mawe

Verfasst: Donnerstag 24. März 2005, 17:21
von Leonidas
Das zweite Array braucht sich gar nicht vernachlässig fühlen denn es kann ja bei der Gelegenheit miterstellt werden:

Code: Alles auswählen

for num, wort in enumerate(a):
    print wort, str(num+1) # damit auch beide Werte Strings sind

Verfasst: Donnerstag 24. März 2005, 17:26
von mawe
Hihi, er kanns nicht lassen :)
Was ist denn wenn das 2. Array so aussiet

Code: Alles auswählen

b = ["x","y","z"]
Oder sind wir jetzt rassistisch und die 2. dürfen nur numerische Werte in aufsteigender Reihenfolge enthalten damit sie mitspielen dürfen? :D

Gruß, mawe

Verfasst: Donnerstag 24. März 2005, 17:33
von Leonidas
mawe hat geschrieben:Hihi, er kanns nicht lassen :)
Was ist denn wenn das 2. Array so aussiet

Code: Alles auswählen

b = ["x","y","z"]
Oder sind wir jetzt rassistisch und die 2. dürfen nur numerische Werte in aufsteigender Reihenfolge enthalten damit sie mitspielen dürfen? :D
Dann ist okay, dann muss man es so machen wir du (Im anderen Fall: TMTOWTDI - There's more than one way to do it).
Da aber Hehejo aber eine Liste mit Zahlen vorgegeben hat, die aufsteigend sortiert sind, habe ich gedacht, dass Hehejo genau sowas machen will. Denn ich benötige sowas schon von ab und zu und da ist erst das erstellen einer Liste und dann das zippen eher unpraktisch, da kommt enumerate() gerade recht (außerdem ist enumerate() so ein hübsches Gimmick aus Python 2.3 und ich liebe es die neuesten Python Funtionen zu nutzen :D).

Verfasst: Donnerstag 24. März 2005, 17:37
von mawe
enumerate() find ich auch cool, war schon ein guter Hinweis von Dir.

Gruß, mawe

Verfasst: Donnerstag 24. März 2005, 17:47
von hehejo
Danke für die Antworten.

Aber ich habe mir wohl das falsche Beispiel herrausgesucht :-)
Eigentlich sind beide Listen mit Strings gefüllt.

Werde demnächst testen ob ich mit dem zip (kannte ich noch gar nicht) mein Problem lösen kann.

Was ich eigentlich machen wollte:
Aus einer csv-Datei die erste Zeile auslesen. So weiß ich die Bezeichner (keys) für die map.
Dann jede Zeile einzeln lesen und dann in etwas so:

Code: Alles auswählen

def csv(filename):
  f = open(filename, "r")
  bezeichner = f.readline().rstrip("\n").split(";")
  content = f.readlines()
  f.close()
  _csv = {}
  for line in content:
    if line.startswith("#"):
      continue
    line = line.rstrip("\n").split(";")
    for value, key in zip(line, bezeichner):
       _csv[key] = value
       yield _csv
  raise StopIteration
bringt im Moment diese Fehlermeldung

Code: Alles auswählen

>>> gen = csv("/home/jo/tmp/test.csv")
>>> gen.next()

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in -toplevel-
    gen.next()
  File "/home/jo/tmp/csv.py", line 14, in csv
    raise StopIteration
StopIteration
>>> 
Aber da schau ich mal woran das lag..

Verfasst: Donnerstag 24. März 2005, 20:05
von Leonidas
Okay, mawe du hattest ja recht 8)

Hehejo: Ich habe die CSV Datei aus dem ersten Beispiel genommen, das mit deinem Code kombiniert:

Code: Alles auswählen

def csv(filename):
  f = open(filename, "r")
  bezeichner = f.readline().rstrip("\n").split(";")
  content = f.readlines()
  f.close()
  _csv = {}
  for line in content:
    if line.startswith("#"):
      continue
    line = line.rstrip("\n").split(";")
    for value, key in zip(line, bezeichner):
       _csv[key] = value
       yield _csv
  raise StopIteration

parsed = None
for i in csv('t.csv'):
    parsed = i
print parsed
Und es geht wunderbar.

Verfasst: Donnerstag 24. März 2005, 23:34
von BlackJack
Ich würde das Ergebnis vom aufteilen von `line` nicht wieder `line` nennen, sondern vielleicht eher `values` oder so.

Ist es gewollt, das immer das gleiche Dictionary verwendet wird?

Ansonsten kann man die ``for``-Schleife vermeiden und gleich folgendes schreiben:

Code: Alles auswählen

yield dict(zip(bezeichner, values))

Danke.

Verfasst: Freitag 25. März 2005, 12:11
von hehejo
BlackJack hat geschrieben:Ich würde das Ergebnis vom aufteilen von `line` nicht wieder `line` nennen, sondern vielleicht eher `values` oder so.
hm ja - leuchtet eigentlich ein.
BlackJack hat geschrieben: Ist es gewollt, das immer das gleiche Dictionary verwendet wird?
Ansonsten kann man die ``for``-Schleife vermeiden und gleich folgendes schreiben:

Code: Alles auswählen

yield dict(zip(bezeichner, values))
Ja, das war so gemeint - aber dein Vorschlag ist besser.
An sowas hatte ich gar nicht gedacht!

Danke.

Verfasst: Samstag 26. März 2005, 08:34
von mawe
Hi!

murphy aus dem Ruby-Forum hat mich indirekt daran erinnert, daß Python ein csv-Modul hat. Wäre das nicht ein ziemlich idealer Anwendungsfall?

Code: Alles auswählen

import csv

def get_csv(filename):
    reader = csv.reader(open(filename, "r"),delimiter=";")
    bezeichner = reader.next()
    for row in reader:
        if row[0].startswith("#"): continue
        yield dict(zip(bezeichner, row))

for i in get_csv("test.csv"):
    print i
Gruß, mawe

Verfasst: Sonntag 27. März 2005, 00:35
von BlackJack
Wenn die Kommentarzeilen ('#') nicht wären, dann gäbe es dafür sogar schon einen `csv.DictReader`.

Und schon wieder was gelernt!

Verfasst: Sonntag 27. März 2005, 08:46
von hehejo
Verdammt, ich sollte doch erst mal alle Module durchforsten bevor ich was programmiere...

Aber mir war langweilig...

Schade dass es solch ein Modul noch nicht für C++ gibt. Dort wollte ich das dann nämlich ähnlich per STL ausprobieren..


Danke -- und schon wieder was gelernt!