String "filtern"

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
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Ich habe folgendes Schema:

Code: Alles auswählen

s = "Node 1: 4392\nNode 2: 3489\nNode 3: 4930\nNode 4: 9320\nNode 5: 3920\nNode 6: 5910\nNode 7: 4954\nNode 8: 5499\nNode 9: 8939\nNode 10: 9212\n"
Und möchte den String so filtern, dass ich am Ende eine Liste habe mit:
['4392', '3489', '4930', '9320', '3920', usw...]

Ich hab's schon mit

Code: Alles auswählen

strip(": ")
und

Code: Alles auswählen

split(": ")
(und noch verschiedene Variationen) probiert, hab' jedoch nie das gewünschte Ergebnis bekommen...
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Meinst Du so?

Code: Alles auswählen

>>> s = "Node 1: 4392\nNode 2: 3489\nNode 3: 4930\nNode 4: 9320\nNode 5: 3920\nNode 6: 5910\nNode 7: 4954\nNode 8: 5499\nNode 9: 8939\nNode 10: 9212\n"
>>> from operator import itemgetter
>>> map(itemgetter(1), (i.split(': ') for i in s.strip().split('\n')))
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '9212']
>>> import re
>>> re.findall('Node \d+: (\d+)', s)
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '9212']
Eugenie
User
Beiträge: 7
Registriert: Sonntag 27. Januar 2013, 12:43

So würde das auch gehen, ohne weitere Module.

Code: Alles auswählen

>>> s.split()[2::3]
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '9212']
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Ich würde da das `re`-Modul verwenden und als Regel alle digits auf die kein Doppelpunkt folgt anwenden:

Code: Alles auswählen

>>> s = "Node 1: 4392\nNode 2: 3489\nNode 3: 4930\nNode 4: 9320\nNode 5: 3920\nNode 6: 5910\nNode 7: 4954\nNode 8: 5499\nNode 9: 8939\nNode 10: 9212\n"
>>> re.findall('(\d+)[^:]', s)
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '1', '9212']
mutetella


EDIT: Ich sehe gerade, '10:' ist natürlich doof... Nimm' einen der anderen Vorschläge! :mrgreen:
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

oder direkt über die Indizes:

Code: Alles auswählen

[s[8:12], s[21:25], s[34:38], s[47:51], s[60:64], s[73:77], s[86:90], s[99:103], s[112:116], s[126:130]]
Benutzeravatar
snafu
User
Beiträge: 6876
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

jerch hat geschrieben:

Code: Alles auswählen

>>> re.findall('Node \d+: (\d+)', s)
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '9212']
...wäre mein Favorit.
nezzcarth
User
Beiträge: 1777
Registriert: Samstag 16. April 2011, 12:47

snafu hat geschrieben: ...wäre mein Favorit.
Falls Python nicht zwingend ist und es nur um das Resultat oder Preprocessing geht, wäre mein Favorit:

Code: Alles auswählen

$ awk '{print $3}' nodes.dat
4392
3489
4930
...
Benutzeravatar
snafu
User
Beiträge: 6876
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@nezzcarth: Man braucht keine `cat`-Ausgabe umzuleiten, um mit `awk` Dateien zu lesen. Ein ``awk '{print $3}' nodes.dat`` geht genau so.
nezzcarth
User
Beiträge: 1777
Registriert: Samstag 16. April 2011, 12:47

snafu hat geschrieben:@nezzcarth: Man braucht keine `cat`-Ausgabe umzuleiten, um mit `awk` Dateien zu lesen. Ein ``awk '{print $3}' nodes.dat`` geht genau so.
Weil ich diese Antwort befürchtet habe, hatte ich das noch reineditiert ;) Mag's mit cat trotzdem lieber, weil das ich das "bildlicher" finde.
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

snafu hat geschrieben:
jerch hat geschrieben:

Code: Alles auswählen

>>> re.findall('Node \d+: (\d+)', s)
['4392', '3489', '4930', '9320', '3920', '5910', '4954', '5499', '8939', '9212']
...wäre mein Favorit.
Ist nun auch meiner :wink:
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

Und noch was..
Wenn ich versuche eine Liste mit sehr vielen Unterelementen (Anzahl: 4800) in eine Datei schreibe, wird das in der Datei mit "...," verkürzt. Gibt es eine Methode dies zu umgehen?
Mir fällt nur die Möglichkeit ein, in einer for-Schleife die Unterelemente einzeln in die Datei zu schreiben, aber ich hoffe es geht auch einfacher.

Code: Alles auswählen

with open(filename, "w") as file:
    file.write(str(list))
Ausgabe wäre dann zum Beispiel:
[ 0.19424016 0.20628876 0.212351 ..., 0.59188767 0.59285003 0.59359792]

Aber es sollten alle 4800 Elemente dargestellt werden und nicht nur die ersten 3 und die letzten 3 Elemente.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

barisoezcan hat geschrieben:Wenn ich versuche eine Liste mit sehr vielen Unterelementen (Anzahl: 4800) in eine Datei schreibe, wird das in der Datei mit "...," verkürzt.
Kann es sein, dass Dein Editor, mit dem Du es anschaust, das ausblendet?
barisoezcan hat geschrieben:Mir fällt nur die Möglichkeit ein, in einer for-Schleife die Unterelemente einzeln in die Datei zu schreiben, aber ich hoffe es geht auch einfacher.
Das ist jetzt auch nicht viel komplizierter:

Code: Alles auswählen

f.write(','.join(l))
Übrigens sind file und list keine guten Bezeichner ;)
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

barisoezcan hat geschrieben:Wenn ich versuche eine Liste mit sehr vielen Unterelementen (Anzahl: 4800) in eine Datei schreibe, wird das in der Datei mit "...," verkürzt.
Ist es denn wirklich eine Liste (der Standardtyp)?
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

@jerch:

Warum sind file und list keine guten Bezeichner? Sie beschreiben doch eigentlich genau das, was sie sind. Nämlich eine Datei und eine Liste.

Und dein Lösungsvorschlag funktioniert nicht wirklich. Die Ausgabe ändert sich lediglich zu:
[, ,0,.,3,1,2,6,3,4,0,1, , ,0,.,3,3,1,2,1,1,8,6, , ,0,.,3,3,3,2,8,7,6,1, ,.,.,.,,, , ,0,.,5,3,4,1,6,6,7,6, , ,0,.,5,3,1,7,9,4,9,2,, , ,0,.,5,3,0,7,1,8,0,9,]

Ich glaube nicht, dass mein Texteditor den Rest ausblendet.

Ich vermute eher, dass der "Fehler" bei der Konvertierung der Liste (EDIT: des Numpy-Arrays) zum String passiert.
Zuletzt geändert von barisoezcan am Samstag 13. April 2013, 23:05, insgesamt 4-mal geändert.
barisoezcan
User
Beiträge: 73
Registriert: Freitag 15. März 2013, 19:38

nomnom hat geschrieben:
barisoezcan hat geschrieben:Wenn ich versuche eine Liste mit sehr vielen Unterelementen (Anzahl: 4800) in eine Datei schreibe, wird das in der Datei mit "...," verkürzt.
Ist es denn wirklich eine Liste (der Standardtyp)?
@nomnom:

Es wurde mit numpy.random.rand(x, y, z) angelegt.
Dann ist es ein Numpy-Array, oder?
Und warum passiert das bei einem großen Numpy-Array, dass es nicht vollständig ausgegeben wird?
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

barisoezcan hat geschrieben:Warum sind file und list keine guten Bezeichner? Sie beschreiben doch eigentlich genau das, was sie sind. Nämlich eine Datei und eine Liste.
Weil "file" und "list" Namen von "built-in" Funktionen sind. So können sich solche Probleme ergeben:

Code: Alles auswählen

>>> list = [1,2,3]
>>> list(("foo", "bar", "baz")) # Versuch, Tupel in Liste umzuwandeln, aus welchem Grund auch immer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
barisoezcan hat geschrieben:Und warum passiert das bei einem großen Numpy-Array, dass es nicht vollständig ausgegeben wird?
Numpy-Arrays haben eine eigene "__str__"-Methode, die eben nur die je ersten und letzten drei Elemente anzeigt.
BlackJack

@barisoezcan: Das passiert weil `str()` eine Zeichenkettendarstellung ist die sich ein menschlicher Benuzter anschauen kann. Niemand möchte wirklich ein Array mit tausenden oder auch nur hunderten von Elementen tatsächlich *sehen*. Damit kann man doch gar nichts anfangen. Darum sind die `numpy`-Typen so nett und machen die Auslassungspunkte bei Strukturen die sowieso zu gross sind, als das sie ein Mensch sinnvoll erfassen kann. Das spart Zeit, Speicher, und Nerven.

Auch eine normale Liste würde man nicht mit `str()` umwandeln und in eine Datei schreiben. Damit kann man dann doch gar nichts anfangen. Die wieder einzulesen würde komplizierter als es sein müsste.

Wenn Du 2D-Daten schreiben möchtest, dann gibt es ganz allgemein das `csv`-Modul beziehungsweise die entsprechenden Funktionen im `numpy`-Modul zum Schreiben in Dateien.
Benutzeravatar
snafu
User
Beiträge: 6876
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

barisoezcan hat geschrieben:Warum sind file und list keine guten Bezeichner? Sie beschreiben doch eigentlich genau das, was sie sind. Nämlich eine Datei und eine Liste.
Sie beschreiben den Daten*typen*, nicht aber deren Inhalt bzw Verwendungszweck. Ich gebe zu, dass man so manches Mal auch nur bei etwas sehr Allgemeinem, wie `data` statt `list` oder `outstream` statt `file` landet. Aber das ist IMHO trotzdem noch besser als die von dir gewählten Namen.

In deinem Fall würde sich vielleicht etwas wie `node_values` anbieten. Damit könnte jemand, der deinen Code nachvollziehen will, meiner Meinung nach etwas mehr anfangen als mit `list`.

EDIT: Achja, und die beiden von dir gewählten Namen überschreiben Built-ins, was zu Problemen führen kann, wie ja schon gezeigt wurde.
Antworten