Seite 1 von 1

Dokumentation für split

Verfasst: Montag 23. Juli 2007, 12:19
von Nils83
Hallo!
Kann mir vielleicht jemand sagen, wo ich eine ausführliche Dokumentation für die split Mehtode finden kann?
Habe bis jetzt nur diese gefunden:
http://www.python.org/doc/lib/string-methods.html

Bekomme leider immer diesen Fehler:
ValueError: invalid literal for int() with base 10: 'NODE_COORD_SECTION'

Verfasst: Montag 23. Juli 2007, 12:36
von Rebecca
Laut Fehlermeldung liegt dein Problem bei der int-Methode, der du einen String fuetterst, der sich nicht in eine Zahl umwandeln laesst. Das hat mit split erstmal nichts zu tun.

Verfasst: Montag 23. Juli 2007, 13:11
von Nils83
Danke, aber ich glaube das liegt daran, dass ich falsch "aufspalte".

Kannst du mir evtl erklären wie das mit dem maxsplit funktioniert?
Was bedeutet [5:-2] bei

Code: Alles auswählen

data.split('\n')[5:-2]])

Vielen Dank für deine Hilfe

Verfasst: Montag 23. Juli 2007, 13:21
von Rebecca
Nils83 hat geschrieben:Danke, aber ich glaube das liegt daran, dass ich falsch "aufspalte".
Das kannst du ja ganz einfach nachpruefen, indem du dir ausgeben laesst, was du beim Splitten herausbekommst.
Nils83 hat geschrieben:Kannst du mir evtl erklären wie das mit dem maxsplit funktioniert?

Code: Alles auswählen

>>> "1:2:3:4:5:6:7".split(":")
['1', '2', '3', '4', '5', '6', '7']
>>> "1:2:3:4:5:6:7".split(":", 3)
['1', '2', '3', '4:5:6:7']
Damit gibtst du an, wie oft maximal gesplittet werden soll.
Nils83 hat geschrieben: Was bedeutet [5:-2]
Damit holst du aus einer Sequenz eine Teilsequenz vom fuenften bis zum drittletzten Element:

Code: Alles auswählen

>>> "Hallo Welt!"[5:-2]
' Wel'
Kleiner Tipp: Probier in der interaktiven Python-Shell einfach mal Dinge aus, dabei kann man vieles selbst ganz einfach rausfinden.

Verfasst: Montag 23. Juli 2007, 16:23
von Nils83
Ok, danke


Ein problem hab ich noch. Und zwar habe ich eine Textdatei, die wie folgt aufgebaut ist:
...
1 30000.0000 75000.0000 10 1
2 20000.0000 20000.0000 20 2
3 80000.0000 90000.0000 30 1
...
Nun würde ich gerne die Zeilen, die eine 2 am Ende haben in ein dictionary packen.
Die If Abfrage am Ende geht so leider nicht:

Code: Alles auswählen

def get_plants(data):
	plant = dict([(int(c.split()[0]), 
			(float(c.split()[1]), 
			float(c.split()[2]))) 
			for c in data.split('\n')[7:-2]] if c.split()[4] == 2) 
	print "plant ", plant
Hat jemand ne Idee?

Verfasst: Montag 23. Juli 2007, 17:01
von Costi
jetzt unabhaengig davon, dass ich mit dein code nichts anfangen kann:
"list comprehension"s werden immer in eckigen klammern gescrieben
dh.

Code: Alles auswählen

[for c in data.split('\n')[7:-2]] if c.split()[4] == 2)]
statt

Code: Alles auswählen

for c in data.split('\n')[7:-2]] if c.split()[4] == 2) 
EDIT:
uuups das is wohl gar kine list comprejension....
nimms mir nicht ueberl, aber ich wuerde mir noch ein paar tuts durchlesen.... :lol:

Verfasst: Montag 23. Juli 2007, 17:07
von BlackJack
@Nils83: Ich hätte sogar zwei Ideen. Zum einen gibt das Konstrukt einen `SyntaxError`. Wenn es zu kompliziert ist, um es in einen Ausdruck zu quetschen, ist es durchaus erlaubt mehrere Anweisungen zu benutzen. ;-)

Dann ist es nicht gerade besonders Effizient dauernd `c.split()` aufzurufen nur um dann jeweils ein Element aus dem Ergebnis zu nehmen.

Last but not least, und das kann man wieder ganz gut im Interpreter ausprobieren:

Code: Alles auswählen

In [14]: a = '2 20000.0000 20000.0000 20 2'

In [15]: a.split()
Out[15]: ['2', '20000.0000', '20000.0000', '20', '2']

In [16]: a.split()[4]
Out[16]: '2'

In [17]: a.split()[4] == 2
Out[17]: False

In [18]: a.split()[4] == '2'
Out[18]: True
Mit ein paar mehr Zeilen und ungetestet:

Code: Alles auswählen

from itertools import imap, izip

def make_convert_row(convert_funcs)
    def convert_row(row):
        return [func(column) for func, column in izip(convert_funcs, row)]
    return convert_row

def get_plants(data):
    convert_row = make_convert_row((int, float, float, int, int))
    rows = data.split('\n')[7:-2]
    plants = dict((row[0], (row[1], row[2]))
                  for row in imap(convert_row, rows)
                  if row[4] == 2)
    print 'plants', plants
@Costi: Deine beiden Beispiele sind syntaktisch falsch und ausserdem gibt's mittlerweile Generatorausdrücke mit runden Klammern, wobei man die weglassen kann, wenn sowieso schon Klammern da stehen. Zum Beispiel im Aufruf von `dict()`.

Code: Alles auswählen

In [23]: (x for x in xrange(10) if x % 2)
Out[23]: <generator object at 0x83e970c>

In [24]: list(x for x in xrange(10) if x % 2)
Out[24]: [1, 3, 5, 7, 9]

Verfasst: Dienstag 24. Juli 2007, 07:06
von The Spirit
Nils83 hat geschrieben:Ok, danke


Ein problem hab ich noch. Und zwar habe ich eine Textdatei, die wie folgt aufgebaut ist:
...
1 30000.0000 75000.0000 10 1
2 20000.0000 20000.0000 20 2
3 80000.0000 90000.0000 30 1
...
Nun würde ich gerne die Zeilen, die eine 2 am Ende haben in ein dictionary packen.
Die If Abfrage am Ende geht so leider nicht:

Code: Alles auswählen

def get_plants(data):
	plant = dict([(int(c.split()[0]), 
			(float(c.split()[1]), 
			float(c.split()[2]))) 
			for c in data.split('\n')[7:-2]] if c.split()[4] == 2) 
	print "plant ", plant
Hat jemand ne Idee?
noch ne frage zu deinen zahlen:
brauchst du die überhaupt als float? kommt ja nach dem komma immer nur noch Nullen.
Und damit du sicher immer auf die letzte spalte überprüfst, würde ich
statt

Code: Alles auswählen

for c in data.split('\n')[7:-2]] if c.split()[4] == 2)
lieber

Code: Alles auswählen

for c in data.split('\n')[7:-2]] if c.split()[-1] == 2)
schreiben.
dann kontrolliert er immer nur die letzte spalte, auch wenn mal oder weniger spalten vorkommen

Verfasst: Dienstag 24. Juli 2007, 09:32
von Nils83
Moin!
Vielen Dank für eure Hilfe.

Also bei

Code: Alles auswählen

from itertools import imap, izip

def make_convert_row(convert_funcs)
    def convert_row(row):
        return [func(column) for func, column in izip(convert_funcs, row)]
    return convert_row

def get_plants(data):
    convert_row = make_convert_row((int, float, float, int, int))
    rows = data.split('\n')[7:-2]
    plants = dict((row[0], (row[1], row[2]))
                  for row in imap(convert_row, rows)
                  if row[4] == 2)
    print 'plants', plants
kriege ich folgenden Meldung:
ValueError: empty string for float()
Kannst du mir vielleicht erklären, was dieses make_convert_row genau macht?
noch ne frage zu deinen zahlen:
brauchst du die überhaupt als float? kommt ja nach dem komma immer nur noch Nullen.
Es sollen später mal Koordinaten werden, deshalb brauche ich sie in der Form.

lieber

Code: Alles auswählen

for c in data.split('\n')[7:-2]] if c.split()[-1] == 2)
schreiben.
dann kontrolliert er immer nur die letzte spalte, auch wenn mal oder weniger spalten vorkommen
werd ich mir merken :)

Verfasst: Dienstag 24. Juli 2007, 10:25
von BlackJack
Ups, da fehlt das aufsplitten der Zeilen in Elemente. :oops:

Immer noch ungetestet:

Code: Alles auswählen

from itertools import imap, izip

def make_convert_row(convert_funcs):
    def convert_row(row):
        return [func(column) for func, column in izip(convert_funcs, row)]
    return convert_row

def get_plants(data):
    convert_row = make_convert_row((int, float, float, int, int))
    rows = (row.split() for row in data.split('\n')[7:-2])
    plants = dict((row[0], (row[1], row[2]))
                  for row in imap(convert_row, rows)
                  if row[4] == 2)
    print 'plants', plants
`make_convert_row()` nimmt ein "iterable" von Funktionen entgegen und gibt eine Funktion zurück, die ebenfalls ein "iterable" entgegennimmt und die Funktionen in der Reihenfolge auf die Elemente anwendet.

Am Beispiel:

Code: Alles auswählen

In [14]: convert_row = make_convert_row((int, float, float, int, int))

In [15]: a = '2 20000.0000 20000.0000 20 2'.split()

In [16]: a
Out[16]: ['2', '20000.0000', '20000.0000', '20', '2']

In [17]: convert_row(a)
Out[17]: [2, 20000.0, 20000.0, 20, 2]

Verfasst: Dienstag 24. Juli 2007, 11:35
von Nils83
super! vielen dank!