String auseinandernehmen

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
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Hallo.

Ich versuche aus einer eingegebenen Zeichenkette die Werte in einer Liste zu speichern und die ungültigen Werte (hier: alles außer int) zu löschen.

Code: Alles auswählen

messreihe = '  4 3m 12   3.7  4 cm  x2 5  '
messwerte = messreihe.split()
i = 0

for messwert in messwerte:
    if messwert.isnumeric() == False:
        print(f'{messwert} wir gelöscht')
        del messwerte[i]
    i += 1

print(messwerte)

Aus mir unerklärlichen Gründen wird aber 'x2' nicht gelöscht, obwohl es ja ganz offensichtlich kein int-Wert ist:

Code: Alles auswählen

test = 'x2'
print(test.isnumeric())
Könntet ihr mir bitte die Situation erklären?
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Habe meine Code noch ein wenig abgeändert und nun bin ich noch mehr verwirrt, denn raus kommen soll das Folgende:
|4|
|12|
|4|
|5|
und ich erhalte nur die 4 und die 5:

Code: Alles auswählen

messreihe = '  4 3m 12   3.7  4 cm  x2 5  '
messwerte = messreihe.split()
i = 0

for messwert in messwerte:
    if messwert.isnumeric() == False:
        # print(f'{messwert} wir gelöscht')
        del messwerte[i]
    else:
        print(f'{i}. Eintrag: |{messwerte[i]}|')
    i += 1
Benutzeravatar
__blackjack__
User
Beiträge: 14069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Du löschst aus einer Liste über die Du gleichzeitig iterierst. Beim löschen rücken ja alle nachfolgenden Elemente eins nach vorn, das weiss aber der Iterator nicht, und deshalb werden Elemente übergangen.

Lösche einfach nicht aus Listen sondern erstelle eine neue Liste nur mit den Werten die Du behalten möchtest:

Code: Alles auswählen

In [60]: [text for text in "  4 3m 12   3.7  4 cm  x2 5  ".split() if text.isnumeric()]
Out[60]: ['4', '12', '4', '5']
Wobei es Dich eventuell überraschen könnte was alles so `isnumeric()` ist. Das sind nämlich nicht nur die ASCII-Ziffern:

Code: Alles auswählen

In [61]: "2³".isnumeric()
Out[61]: True
Andererseits:

Code: Alles auswählen

In [62]: "-42".isnumeric()
Out[62]: False
Das wäre aber eine ganze Zahl.

Wenn Du filtern willst was in eine ganze Zahl umwandelbar ist, solltest Du genau das tun: in eine ganze Zahl umwandeln.

Code: Alles auswählen

In [65]: list(more_itertools.filter_except(int, "  4 3m 12   3.7  4 cm  x2 5  ".split(), ValueError))
Out[65]: ['4', '12', '4', '5']
Den Vergleich mit ``something == False`` macht man nicht. Das wäre ``not something``.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

@blackjack: Danke für deine Hilfe. Es tut was es soll. Ich muss aber damit noch ein wenig weiterarbeiten (habe ich hier noch nicht erwähnt).
Aber die Syntax in deinem Beispiel

Code: Alles auswählen

[text for text in "  4 3m 12   3.7  4 cm  x2 5  ".split() if text.isnumeric()]
verstehe ich noch nicht ganz:
was sagt der erste 'text'? Was ist das? Ist das quasi ein weiterer Iterator?
Hast du einen Link zu eine Tutorial für mich, wo man solche Konstrukte lernen kann?

Code: Alles auswählen

messreihe = '  4 3m 12   3.7  4 cm  x2 5  '
messwert = [text for text in messreihe.split() if text.isnumeric()]
print(messwert)
Die Aufgabe hat noch einen Teil B, wo ich die Ausgabe wie umbauen soll:
Ungültige Werte ersetzen
Passen Sie die Lösung aus Aufgabe 1 so an, dass fehlerhafte Werte nicht gelöscht werden, sondern durch 0 ersetzt werden. Zudem soll neben der Anzahl der Messwerte insgesamt auch die Anzahl der gültigen Messwerte ausgegebn werden. Beispiel:

Messreihe eingeben: 4 3m 12 3.7 4 cm x2 5 7
Bereinigte Messreihe (9 Messwerte insgesamt, davon 5 gültige):
|4|
|0|
|12|
|0|
|4|
|0|
|0|
|5|
|7|
Dazu ist es wichtig, dass ich deine o.g. Syntax verstehe....
Benutzeravatar
__blackjack__
User
Beiträge: 14069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ist eine „list comprehension“: ``result = [<expression> for item in iterable if <condition>]`` erzeugt eine Liste mit Elementen die aus <expression> erzeugt werden für Elemente aus `iterable` falls die <condition> zutrifft. In <expression> und <condition> kommt sinnvollerweise `item` for. Als Schleife sähe das so aus:

Code: Alles auswählen

result = []
for item in iterable:
    if <condition>:
        result.append(<expression>)
`messwert` sollte eher `messwerte` heissen. Ist ja mehr als ein Wert.

Das mit der ``if``-Bedingung ist optional bei der „list comprehension“. Bei der abgewandelten Anforderung braucht man die nicht mehr. Dafür eine Fallunterscheidung bei dem Ausdruck der die Elemente erstellt:

Code: Alles auswählen

In [79]: [text if text.isnumeric() else "0" for text in "  4 3m 12   3.7  4 cm  x2 5  ".split()]
Out[79]: ['4', '0', '12', '0', '4', '0', '0', '5']
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten