Seite 1 von 1

buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 15:56
von Rinno
hallo, liebe python gemeinde,
ich suche nach einer Möglichkeit alle Zahlen aus einem String, in meinem Fall ein md5 hash zu isolieren, und als neuen String abzuspeichern. Ich brauche das für einen Zufallsgenerator.

zb soll aus
"b59fa603913495a7650cf909e316d88b"
"59603913495765090931688"
werden.

Klingt einfach, ist es warscheinlich auch. Ich steige aber einfach nicht dahinter.

Ich benutze Python3 und mein bisheriger Ansatz war, den String erstmal in eine Liste umzuwandeln:

Code: Alles auswählen

hash=("b59fa603913495a7650cf909e316d88b")
list=list(hash)
um dann aus der Liste immer wieder mit

Code: Alles auswählen

if "a" in hash:
	hash.remove("a")
else:
	hash=hash
alle objekte mit dem buchstaben a Stück für Stück zu entfernen, und das mit lallen buchstaben von a bis z und am ende die Liste irgendwie wider in einen String zu verwandeln.

Aber das ist finde ich viel zu viel Code für ein so kleines Problem.
Und so richtig funktioniert mein Ansatz auch noch nicht. (ich bekomme keinen string mehr hin)
gibt es eine simplere methode?
Ich wäre echt froh eine zu finden, weil ich hänge hier schon seit einiger Zeit fest :/
Danke im Voraus

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 16:13
von Hyperion
Kleiner Tipp: ``str.isdigit`` existiert ;-) Zudem ``str.join``. Das kann man in einem Generatorausdruck schreiben...
Ansatz:

Code: Alles auswählen

"".<method>(<Test> for c in hash)
"<method>" und "<Test>" musst Du nun mit den beiden genannten Tipps umsetzen.

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 16:47
von snafu

Code: Alles auswählen

import re
hash = "b59fa603913495a7650cf909e316d88b"
re.sub("\d+", "", hash) # => 'bfaacfedb'
`"\d+"` findet alle in `hash` enthaltenen Ziffernfolgen (Digits), wobei das `+` für die Bedingung "ein oder mehrere" steht. Auf jede Fundstelle wird das zweite Argument (hier: leerer String) zur Ersetzung angewendet. `hash` selbst ist schließlich die Zeichenkette, auf welcher die Ersetzungen ausgeführt werden sollen.

Übrigens klappt ein `"\d"` in diesem Fall genau so. Allerdings würde die Ersetzung dann theoretisch für jede Ziffer einzeln angewendet werden, was zu schlechterer Laufzeit führen dürfte. Mögliche interne Optimierungen, die möglicherweise in dem hinter `re.sub()` "liegenden" Code stattfinden, lasse ich mal bewusst außen vor, da diese nicht garantiert sind. Diese Anmerkung spielt prinzipiell auch nur eine Rolle in der Praxis (im Sinne von spürbar schlechterer Laufzeit), wenn man es mit größeren Texten zu tun hat (trifft bei Hashwerten wohl eher weniger zu). Andererseits sollte man IMHO auch solche Sachen von Anfang an "korrekt" machen. :)

Achso, und eigentlich ist dein Thread eher ein Thema für das Forum "Allgemeine Fragen". Vielleicht für's nächste Mal beachten... ;)

EDIT: Und falls man reguläre Ausdrücke vermeiden möchte, geht's natürlich auch "zu Fuß" in reinem Python:

Code: Alles auswählen

"".join(char for char in hash if char.isalpha())

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 17:09
von Rinno
Danke euch beiden für eure hilfe :)
snafu hat mich auf den richtigen weg gebracht. =D

Code: Alles auswählen

import re
re.sub("[^0-9]", "", hash)
ersetzt meinen Din a4 seiten langen code zuferlässig :D

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 17:25
von cofi
Ich bevorzuge da ja den Weg, den Hyperion aufgezeigt hat:

Code: Alles auswählen

In [4]: hash = "b59fa603913495a7650cf909e316d88b"

In [5]: ''.join(c for c in hash if c.isdigit())
Out[5]: '59603913495765090931688'
Und mit filter:

Code: Alles auswählen

In [6]: filter(operator.methodcaller('isdigit'), hash)
Out[6]: '59603913495765090931688'

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 17:33
von snafu
Oder hier: Auch mit `filter()` aber ohne `methodcaller()`:

Code: Alles auswählen

filter(lambda c: c.isalpha(), hash)
Man sieht schon: "There should be only one preferred way to do it..." (oder so ähnlich) :mrgreen:

EDIT: Ups. jetzt merk ich erstmal, dass ich die ganze Zeit das Gegenteil mache. Es sollen ja die *Buchstaben* entfernt werden. :oops:

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 17:37
von snafu
Rinno hat geschrieben:

Code: Alles auswählen

import re
re.sub("[^0-9]", "", hash)
Dafür gibt's übrigens ne kürzere Lösung:

Code: Alles auswählen

re.sub("\D+", "", hash)
Das ersetzt alle "Nicht-Digits".

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 18:06
von BlackJack
Ebenfalls ein Ansatz wäre die `translate()`-Methode auf Zeichenketten.

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 20:44
von /me
BlackJack hat geschrieben:Ebenfalls ein Ansatz wäre die `translate()`-Methode auf Zeichenketten.
Und der beste Ansatz wäre es, einen bestehenden Zufallszahlengenerator zu verwenden. :mrgreen:

Re: buchstaben aus einem string entfernen

Verfasst: Samstag 16. Juni 2012, 21:38
von snafu
/me hat geschrieben:Und der beste Ansatz wäre es, einen bestehenden Zufallszahlengenerator zu verwenden. :mrgreen:
Du hinterfragst den Sinn von User-Anfragen? :o

Re: buchstaben aus einem string entfernen

Verfasst: Sonntag 17. Juni 2012, 08:34
von /me
snafu hat geschrieben:Du hinterfragst den Sinn von User-Anfragen? :o
Das ist wie üblich Hilfe zur Selbsthilfe. Der Fragesteller sollte sich darüber klar sein was er da tut. Ich weiß nicht, ob ihm alle Auswirkungen dieses Ansatzes klar sind, wie zum Beispiel eine extreme Ungleichverteilung von Zahlen. Eine 1 wird deutlich seltener als Ergebnis herauskommen als beispielsweise eine 111

Re: buchstaben aus einem string entfernen

Verfasst: Sonntag 17. Juni 2012, 10:19
von snafu
Naja, wenn einfach nur Zufallszahlen gebraucht werden, dann ist die Empfehlung natürlich random.randint():

Code: Alles auswählen

[random.randint(0, 9) for _ in xrange(30)]
...generiert 30 zufällige Zahlen zwischen 0-9.

Re: buchstaben aus einem string entfernen

Verfasst: Sonntag 17. Juni 2012, 11:29
von Dav1d
snafu hat geschrieben:Naja, wenn einfach nur Zufallszahlen gebraucht werden, dann ist die Empfehlung natürlich random.randint():

Code: Alles auswählen

[random.randint(0, 9) for _ in xrange(30)]
...generiert 30 zufällige Zahlen zwischen 0-9.
Und `join` um daraus einen String zu machen:

Code: Alles auswählen

''.join(random.randint(0, 9) for _ in xrange(30))

Re: buchstaben aus einem string entfernen

Verfasst: Sonntag 17. Juni 2012, 12:39
von BlackJack
Wobei man bei diesen Zeichenketten auch wieder aufpassen muss, dass man keine gleichmässige Verteilung hat, wenn man sie als Zahlen auffasst. Irgend so etwas wird Rinno ja wahrscheinlich vorhaben, wenn er die Ziffern irgend wo heraus filtert.

Das klingt sowieso komisch aus einem Hash-Wert in Hexadezimal-Schreibweise nur die Ziffern heraus zu fischen, die auch in Dezimaldarstellungen gültig wären. Warum möchte man auf diese Weise 128 Bit-Werte ungleichmässig verteilt auf einen ≈106,3 Bit Wertebereich abbilden‽