2016-03-28 9 views
2

Was ist der sauberste Weg, um eine Liste der numerischen Werte in einer Zeichenkette zu erhalten?Der sauberste Weg, um eine Liste der numerischen Werte in einer Zeichenkette zu erhalten

Zum Beispiel:

string = 'version_4.11.2-2-1.4' 
array = [4, 11, 2, 2, 1, 4] 

Wie Sie vielleicht verstehen, ich brauche Versionen zu vergleichen.

Mit "sauberste", meine ich so einfach/kurz/lesbar wie möglich.

Auch wenn möglich, dann bevorzuge ich integrierte Funktionen über regexp (import re).

Das ist, was ich so weit gekommen, aber ich glaube, dass es eher ungeschickt ist:

    :

    array = [int(n) for n in ''.join(c if c.isdigit() else ' ' for c in string).split()] 
    

    Merkwürdigerweise habe ich eine Antwort zu finden auf SO nicht in der Lage gewesen,

  • In this question werden die Eingangs numerischen Werten ausgegangen von weißen Flächen
  • In this question, die Eingangs numerische Werte getrennt angenommen werden durch Leerräume getrennt werden
  • In this question, nur der Benutzer für einen einzigen numerischen Wert am Anfang des Strings fragt nur
  • In this question, der Benutzer für einen einzigen numerischen Wert aller Ziffern verketteten

Dank

Antwort

6

Gerade Spiel fragt auf aufeinanderfolgenden Ziffern:

map(int, re.findall(r'\d+', versionstring)) 

Es ist egal, was zwischen den Ziffern ist; \d+ entspricht so vielen Ziffern, wie in einer Zeile gefunden werden können. Dies gibt Ihnen die gewünschte Ausgabe in Python 2:

>>> import re 
>>> versionstring = 'version_4.11.2-2-1.4' 
>>> map(int, re.findall(r'\d+', versionstring)) 
[4, 11, 2, 2, 1, 4] 

Wenn Sie Python 3 verwenden, map() gibt Ihnen ein iterable map Objekt, also entweder rufen list() auf das, oder eine Liste Verständnis verwenden:

[int(d) for d in re.findall(r'\d+', versionstring)] 
+0

Danke. Ich benutze Python 2. Also nehme ich es (auch von allen anderen Antworten), dass es nicht viel mehr gibt, was mit eingebauten Funktionen erreicht werden kann, und dass "re" die sauberste Lösung ist. Ist das korrekt? –

+0

@barakmanos 're' ist Teil der Standardbibliothek, behandeln Sie es wie ein eingebautes. Es ist die sauberste Lösung für Ihr spezifisches Problem, ja. –

5

Ich würde das auch mit einem regulären Ausdruck lösen.

Ich bevorzuge re.finditer über re.findall für diese Aufgabe. re.findall gibt eine Liste, re.finditer einen Iterator zurückgibt, so mit dieser Lösung werden Sie nicht eine temporäre Liste von Strings erstellen:

>>> [int(x.group()) for x in re.finditer('\d+', string)] 
[4, 11, 2, 2, 1, 4] 
0

Regex ist definitiv der beste Weg zu gehen, wie @MartijnPieters eindeutig beantworten zeigt, aber wenn Sie Ich möchte es nicht verwenden, Sie können wahrscheinlich kein Listenverständnis verwenden. Dies ist, wie Sie es tun könnte, aber:

def getnumbers(string): 
    numberlist = [] 
    substring = "" 
    for char in string: 
     if char.isdigit(): 
      substring += char 
     elif substring: 
      numberlist.append(int(substring)) 
      substring = "" 
    if substring: 
     numberlist.append(int(substring)) 
    return numberlist 
+0

Ich denke, es ist nicht viel besser als das, was ich bereits in meiner Antwort habe. Danke auf jeden Fall. –

+0

Sie müssen auf einen Rest prüfen; Sie werden die letzte Zahl in einer Zeichenfolge verpassen, wenn nicht Ziffern folgen. –

+0

@MartijnPieters: Das ist ein Bug, den ich nicht bemerkt habe, aber jetzt ist er behoben. Vielen Dank. – zondo

0

Sie sind alle Zeichen Tracking und prüfen, ob es sich um eine Ziffer ist, wenn ja Sie es auf eine Liste hinzufügen, Ruft langsam für größere Saiten.

Lasst uns sagen,

import re 
    string='version_4.11.2-2-1.4.9.7.5.43.2.57.9.5.3.46.8.5' 
    l=map(int, re.findall('\d+',string)) 
    print l 

Hoffentlich sollte dies funktionieren. Nicht sicher in der Antwort oben, warum verwenden wir 'r'.

0

Sie können dies einfach mit regulären Ausdrücken auflösen.

import re 
string = 'version_4.11.2-2-1.4' 
p=re.compile(r'\d+') 
p.findall(string) 
Verwandte Themen