For in Pythonic Way

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
Benutzeravatar
gulper
User
Beiträge: 1
Registriert: Mittwoch 17. April 2024, 09:02

Moin,

Ja ich bin Anfänger, aber vor Allem Umsteiger und Wiedereinsteiger.
Und ich komme mit meinen Tutorials bei dieser Frage nicht weiter.
Mit Python und seinen Spezifika bin ich noch nicht wirklich vertraut.
Der folgende Codeteil funktioniert zwar, scheint mir aber keinesfalls Pythonic, wie ihr das so gerne ausdrückt.

Code: Alles auswählen

def convlist(arr):
    for i in range(0,len(arr)):
        arr[i][1]=min2h(arr[i][1])
    return arr
Eigentlich soll in einer Liste von Listen nur jedes 2 te. Listenelement in eine Funktion hineingegeben werden und ersetzt werden.
Das muss doch eigentlich viel eleganter gehen.
Die folgende Idee scheitert schon daran den Wert zurückzugeben und zu überschreiben

Code: Alles auswählen

for l in arr:  
    l[1]=min2h(l[1])

Womit kann ich das vereinfachen, und wie muss ich weitersuchen?
Evtl. hat ja auch einer einen Ein- oder Zweizeiler, an dem weiterlernen kann?

Gruß
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also erst mal ist es unpythonisch, Datenstrukturen zu veraendern, statt neue Datenstrukturen mit veraenderten Werten zu produzieren. Das reduziert dann naemlich deutlich die Menge der Fehler, weil eine Funktion das, was sie gemacht, zurueckgibt, statt ein uebergebenes Argument still und heimlich zu veraendern. Und was man, *wenn* man schon so arbeiten, *niemals* macht, ist dieses veraenderte Argument dann auch noch zurueck zu geben, weil das die Erwartung weckt, dass es sich um eine neue Datenstruktur handelt. ZB der Grund, warum list.sort *None* zurueckgibt, und man stattdessen

Code: Alles auswählen

neu = sorted(alt)
benutzt.

Und prinzipiell sehe ich da keinen Grund, warum dein zweites Snippet da nicht hilft, denn fuer mich geht das problemlos. Einmal schlecht zur illustration, und einmal besser:

Code: Alles auswählen

import pprint

def new_value(v):
    return v * 2


def transform_bad(l):
    for item in l:
        item[1] = new_value(item[1])


def make_new(item):
    return [item[0], new_value(item[1])]

def transform_good(l):
    return [make_new(item) for item in l]

def main():
    l = [
        [0, 1],
        [1, 1],
        [2, 1],
    ]
    transform_bad(l)
    pprint.pprint(l)
    new_l = transform_good(l)
    pprint.pprint(l) # unmodified
    pprint.pprint(new_l)

# main guard
if __name__ == '__main__':
    main()
Man kann make_new jetzt auch zB durch ein lambda ersetzen, um es zu inlinen, aber lesbarer ist in meinen Augen besser.

Zu guter Letzt ist eine Liste von Listen dieser Art eher ungewoehnlich, es klingt eher nach einer Liste von Tupeln (die man dann auch passenderweise nicht veraendern kann), oder gar gleich eine Liste von Objekten, wobei man ja mit namedtuple oder attrs sich sowas leichtgewichtig bauen kann.
Antworten