Listen von Listen mit Aufzählungen

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
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Hallo zusammen,
ich möchte gerne eine Funktion erstellen, die als Parameter eine Liste erwartet und die mir dann eine Rückgabe gibt von Listen mit Aufzählungen zu der Eingabeliste. Zum einfacheren Verständnis hier mal ein Beispiel: Eingabe: [3, 7, 2] Funktion gibt zurück: [ [1, 2, 3], [1, 2, 3, 4, 5, 6, 7], [1, 2] ].
Ich komme da nicht wirklich weiter. Ich habe erstmal eine for-Schleife gesetzt um die Länge der eingegeben Liste zu durchlaufen. Aber was muss ich denn nun machen, damit der das erste Listenelement nimmt und dann eine Liste mit der Aufzählung gefüllt? Und dann mit den nächsten weiter macht ( ich denke eine weitere for schleife)?!
Danke für Eure Hilfe

Code: Alles auswählen

def f4(L):

    Lges = [ ]   ## Hier möchte ich die erstellten Listen ablegen
    if type(L) == list:
        print('Das war eine richtige Eingabe nun folgt das Ergebnis: ')
        for e in range(len(L)):

            pass
                        

     else:
        print('Falsche Eingabe')

BlackJack

@duodiscus: Du fängst schon falsch an. Wenn Du über die Elemente von `L` iterieren möchtest, dann tu das doch einfach. ``for item in L:``. Dieser Umweg über einen Index ist total unnötig.

Die Typprüfung ist ”unpythonisch”. Warum sollte der Benutzer da nicht auch ein Tupel übergeben dürfen? Oder irgend ein anderes Objekt über das man iterieren kann?

Die Namen `L` und `Lges` entsprechen in der Schreibweise weder dem Style Guide for Python Code, noch sind es inhaltlich gute Namen. Man muss als leser raten was der Wert dahinter eigentlich bedeuten soll.

Eine Liste mit einer Aufzählung kann man mit `range()` und `list()` erstellen. Und die Ergebnisliste mit den Aufzählungen mit einer „list comprehension”. Damit wäre diese Funktion ein ganz simpler Einzeiler.
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Das mit der Typprüfung wurde mir so vorgegeben. Es steht in der Aufgabe, das ich nur eine Liste übergeben soll. Da fehlt auch noch z.B. das es nur Int Werte sein sollen. Aber das ist ja zurzeit auch gar nicht mein Problem.

Eine Liste mit einer Aufzählung kann ich auch erstellen. Nur mir fehlt irgendwie der Punkt, das wenn er das erste Element hat, dann eine neue Liste bis zu diesem Element befüllt.
Eine normale Auflistung ist net das Problem:

Code: Alles auswählen

def f(n):
    L = [ ] 
    for i in range(n+1):
        
        L.append(i)

    print(L)
    
BlackJack

@duodiscus: Das man nur eine Liste übergeben soll heisst ja nicht das man das auch prüfen muss. Man übergibt halt einfach nur eine Liste.

Ich verstehe jetzt das Problem nicht, Du hast doch da eine Funktion die fast so eine Liste mit einer Aufzählung erstellt. Die ist nicht ganz korrekt, weil nicht mit er 1 angefangen wird, aber das ist ja einfach zu beheben. Und die Funktion ist reichlich umständlich weil man sich `L` und die Schleife komplett sparen kann wenn man die `list()`-Funktion verwendet um die Liste zu erstellen. Und dann braucht man auch `f()` nicht zwingend.

Du musst genau *das* doch jetzt nur für jedes Element vom Argument von `f4` tun und die Ergebnisse davon in einer Liste sammeln. Ich wiederhole es noch mal: eine „list comprehension” drängt sich hier geradezu auf.
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Okay mit list comprehensions versuche ich es dann mal. Gut wenn ich eine erstelle wie diese:

Code: Alles auswählen

def f(L):

    Lges = [x**2 for x in L]
    return Lges

>>> f([3, 4, 5])
[9, 16, 25]
>>> 
Mein Problem ist: Statt x**2, müsste ich jetzt ja eine weitere Liste erstellen, die mit Werten gefüllt wird und dann automatisch Lges hinzugefügt wird. Nur ich weiss nicht wie ich das jetzt machen soll das er jetzt eine Liste in der Liste erstellt und die wie in diesem Beispiel füllt [ [1, 2, 3] , [1, 2, 3, 4] , [1, 2, 3, 4, 5]. Sprich das erste Element von L nimmt, dann bis wie hier 3 hochläuft und in einer separaten Liste ablegt und diese wiederum in Lges. Ich habe mich da jetzt schon so lange mit beschäftigt das es wohl nix mehr bringt :D
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

Du machst doch fast das selbe in Deinem Beispiel. Du nimmst eine Zahl x, übergibst sie der Potenzfunktion, die daraus eine andere Zahl macht. Was Du also brauchst, ist eine Funktion, die aus einer Zahl die passende Liste generiert.
BlackJack

@duodiscus: Eine Funktion die so etwas macht hast Du doch im Beitrag davor gehabt. Ansonsten noch mal: `range()` und `list()`. Mehr braucht man nicht. Mit `range()` einen Iterator mit den Zahlen erstellen und daraus dann mit `list()` die Liste mit den Elementen. Einfacher geht's kaum.

Der Name `Lges` ist hier ziemlich überflüssig. Man kann das Ergebnis auch direkt zurück geben ohne es noch mal an einen Namen zu binden.
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Danke für Eure Tipps. Habe es jetzt endlich kapiert :D. War wirklich sehr einfach, aber wenn man sich in etwas verrannt hat kann die Lösung manchmal noch so nah sein, aber man sieht sie nicht. Habe es jetzt schön kurz in einem Einzeiler gemacht.

Code: Alles auswählen

[list(range (1, x+1)) for x in L]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du solltest die Liste von Längen nicht ``L`` nennen. Zum einen sollten Namen klein geschrieben werden (außer bei Modul globalen) und zum anderen sinnvoll benannt. Wofür steht denn ``L``?

Es würde mich durchaus interessieren, wofür Du diese Funktion eigentlich brauchst? Also die Listen von aufsteigenden Sequenzen sind ja vermutlich kein Selbtszweck, sondern Du willst damit ja vermutlich etwas anstellen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Hausaufgaben sind halt manchmal nicht sinnvoll. ;-)

Zitat: „Das mit der Typprüfung wurde mir so vorgegeben. Es steht in der Aufgabe, das ich nur eine Liste übergeben soll.”
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben:@Hyperion: Hausaufgaben sind halt manchmal nicht sinnvoll. ;-)
Ah... hatte ich überlesen! :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Habe jetzt doch noch eine weitere Frage. Habe alles soweit ausgearbeitet wie es verlangt wird. Denn es soll noch geprüft werden ob der übergebene Parameter wirklich eine Liste ist und dann noch zusätzlich ob es sich dabei um (!) positive Int Werte handelt.
Habe es jetzt zurzeit so, allerdings funktioniert das nicht. Die zweite Verzweigung mit dem Int-Werten funktioniert scheinbar nicht so wie ich mir das mit der Logik so vorstelle. Kann mir da jemand weiterhelfen?

Code: Alles auswählen

def f(L):
    if type(L)==list:

        for i in L:
            if i == type(int):
                
                Lges = [list(range (1, x+1)) for x in L]
                return Lges
            else:
                print('kein int')
            

    else:
        print('Falsche Eingabe')
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Das Prüfen auf Typen erledigt man mit ``isinstance``.

Generell ist das aber in einem Programm absolut "unpythonisch". In Python "herrscht" Duck Typing - da ist einem der spezielle Typ ziemlich egal; auf das Verhalten kommt es an! Aber ok, ist ja offenbar einer Hausaufgabe.

Für die Subteile 2 und 3 wäre die Funktion ``all`` für Dich interessant!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

die verschachtelte for-Schleife ist ziemlicher Quatsch. Das Element in der Liste müßte `type` sein, damit die if-Abfrage erfüllt wird. Und auch wenn Du die if-Abfrage richtig schreiben würdest, so prüfst Du nur, ob irgendwo ein int in der Liste ist.
Explizit auf Typen zu prüfen, würde ich in Python als Programmierfehler bezeichen. Fehler, wie kein Typ, der die __trunc__-Methode implementiert, würde man über eine Exception viel besser abfragen.
duodiscus
User
Beiträge: 97
Registriert: Sonntag 6. April 2014, 16:10

Also das von Hyperion hat mir schon sehr gut weitergeholfen.
Habe es jetzt auch so, das es funktioniert. Das einzige was noch hakelig ist, ist das er ja prüfen soll ob alle int Werte auch positiv sind. Wenn ich jetzt eine Liste als Parameter eingebe und und erste Listenelement negativ eingebe, funktioniert es auch und er erkennt dieses und gibt die Fehlermeldung aus. Wenn allerdings ein Element nach dem ersten negativ ist, gibt er die Meldung nicht mehr aus und er erzeugt dafür einfach nur eine leere Liste. Habe ich einen Fehler mit den Einrückungen gemacht?

Code: Alles auswählen

def f(L):
    if type(L)==list:

        for i in range(len(L)):
            if isinstance(L[i], int) == True and L[i] >= 0:
                Lges = [list(range (1, x+1)) for x in L]
                return Lges
            
                
            else:
                print('Fehler. Sie haben keinen Int-Wert eingegeben.')
                break
                
       
                
    
    else:
        print('Falsche Eingabe. Bitte neu starten. Nur Listeneingabe möglich.')



BlackJack

@duodiscus: Wie Sirius3 schon gesagt hat ist die ``for``-Schleife so wie sie da steht unsinnig. Zumal `i` eine unnötige Indirektion ist, denn man kann in Python *direkt* über die Elemente von Listen iterieren. Wenn Du `range()` und `len()` auf diese Art zusammen verwendest, ist das in 99,9% der Fälle ein falscher Entwurf.

Schreib Dir für den Test vielleicht eine eigene Funktion. Dann kannst Du die Dinge gar nicht erst so komisch vermischen wie Du das hier getan hast.
Antworten