for Schleife, Liste 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
Xerabell
User
Beiträge: 3
Registriert: Sonntag 10. November 2019, 14:50

Hey,
ich möchte eine Funktion schreiben, die ein Argument vom Typ "list" erwartet und von dieser eine copy erstellt. Diese copy soll am Ende aber nur die Elemente enthalten, die vom Typ "int" oder "float" sind, sowie in einem bestimmten Bereich z.b nur von 10 bis 30.
Ich habe schon alles mir bekannte versucht und komme nicht auf den richtigen Code. :(
Kann mir jemand helfen? :roll:

def filter_list (elements):
elements2 = elements.copy()
for n in elements2:
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie würdest Du denn den Typ einer Variable bestimmen? Oder wie würdest Du ermittelten ob erlittene Zahl im gewünschten Beitrag ist?

Statt die Liste zu kopieren, fang mit einer leeren Liste an und füge der nur dir gewünschten Elemente der übernehmen übergeben Liste hinzu.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ich würde nicht den Ansatz nehmen die Liste zu kopieren und dann aus der Kopie alles unpassende rauszuwerfen. Stattdessen würde ich mit einer leeren Liste für das Ergebnis beginnen und dort alles aus dem Original hinzufügen, was die Bedingungen erfüllt.

edit: Wie Sirius auch schon schrieb während ich meine Antwort verfasste ...
Xerabell
User
Beiträge: 3
Registriert: Sonntag 10. November 2019, 14:50

Erstmal Danke für die Antworten. :)

Jetzt habe ich es so gemacht:
def filter_list (elements):
elements2 = [ ]
for n in elements:

if n is type(0) or type(1.0):
if n >= 1 and n <= 50:
elements2.append(n)
continue

elif n is not type(0) or type(1.0):
continue


return elements2


assert filter_list([0,10,55]) == [10]
assert filter_list([10,"100", 10]) == [10, 10]


Nun macht mir aber der "str" Probleme.
TypeError: '>=' not supported between instances of 'str' and 'int'
Xerabell
User
Beiträge: 3
Registriert: Sonntag 10. November 2019, 14:50

Hab es hinbekommen danke :D
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Zahl oder ein String ist niemals vom Typ einer Zahl. Und `or` ist kein umgangssprachliches Oder, sondern ein logisches Oder bedeutet, entweder ist der Ausdruck vor dem or wahr oder der danach. Der davor ist es nie, der danach immer; die if-Abfrage ist also unsinnig, da immer wahr.
Das `continue´ solltest Du möglichst nicht benutzen und ist in Deinem Fall sogar komplett überflüssig. Was willst Du denn mit der elif-Bedingung ausdrücken?
Bleibt also:

Code: Alles auswählen

def filter_list (elements):
    elements2 = []
    for n in elements: 
        if n >= 1 and n <= 50:
            elements2.append(n)
    return elements2
Und da vergleichst Du Strings mit Zahlen, was natürlich nicht klappen kann. Typprüfung macht man mit `isinstance`.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Der Code geht beim Vergleich noch ein klein wenig schöner.

Code: Alles auswählen

def filter_list (elements):
    elements2 = []
    for n in elements: 
        if 1 <= n <= 50:
            elements2.append(n)
    return elements2
Jetzt brauchst du nur noch vor dem Vergleich auf den Wertebereich mit isinstance überprüfen ob auch wirklich ein Integer- oder Float-Wert vorliegt.

Wenn du das hast, dann können wir auch gerne noch zeigen wie das alles mit einer List Comprehension zu einem Einzeiler wird.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich würde ja eine Funktion für die Validierung basteln und davon abhängig die Liste aufbauen:

Code: Alles auswählen

def is_valid(n):
    try:
        return 1 <= n <= 50
    except TypeError:
        return False

numbers = [10, 0, -10, "100", "0", 1.0, -47.11, 42.0815]
print([n for n in numbers if is_valid(n)])
Antworten