Seite 1 von 1
String auseinandernehmen
Verfasst: Dienstag 27. Dezember 2022, 11:34
von Feedback1000
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:
Könntet ihr mir bitte die Situation erklären?
Re: String auseinandernehmen
Verfasst: Dienstag 27. Dezember 2022, 11:42
von Feedback1000
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
Re: String auseinandernehmen
Verfasst: Dienstag 27. Dezember 2022, 11:50
von __blackjack__
@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:
Andererseits:
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``.
Re: String auseinandernehmen
Verfasst: Dienstag 27. Dezember 2022, 13:45
von Feedback1000
@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....
Re: String auseinandernehmen
Verfasst: Dienstag 27. Dezember 2022, 13:59
von __blackjack__
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']