Seite 1 von 1

Python: Schleifen iterierung Varianten

Verfasst: Freitag 11. Oktober 2019, 21:21
von Chaostheorie
Ich bin seit längerem am programmieren mit Python und wollte eine Frage zur Best Practice/ effizentieren Schreibweise bei der Iterierung von Python stellen.
Normalerweise versuche ich so oft wie möglich:

Code: Alles auswählen

for record in list:
	print(record)
zu verwenden. Aber ist das wirklich besser/ macht es einen Unterschied zu:

Code: Alles auswählen

for i in range(len(list)):
	print(list[i])
Grund der Frage: Ich arbeite seit kürzerem mit einem großen Dataset und wollte aufgrund meines schwächelnden PS's vorallem bei Schleifen durch list comprehensions Zeit sparen aber ich frage mich welche der Bieden oben genannten Varianten besser währe.
Danke im Vorraus, Chaostheorie

Re: Python: Schleifen iterierung Varianten

Verfasst: Freitag 11. Oktober 2019, 21:48
von sparrow
Die zweite Variante ist ein Anti-Pattern in Python. Es macht schlicht keinen Sinn es so zu tun.
Was schneller ist, kanst du ja einfach selbst herausfinden, indem du z.B. mit timeit die Zeit misst.
Aber wie sollte denn die zweite Variante deiner Meinung nach Zeit oder Resourcen sparen?

Re: Python: Schleifen iterierung Varianten

Verfasst: Freitag 11. Oktober 2019, 23:26
von __blackjack__
@Chaostheorie: List comprehensions sind nicht dazu da um Zeit zu sparen, sondern um Code lesbarer zu machen. Wobei list comprehensions auch das nicht automatisch machen, man sollte sie zum Beispiel nicht zu stark schachteln.

Wenn es lesbar geschrieben in Python zu langsam ist, dann sollte man über die Algorithmen nachdenken, einen leistungsfähigeren Rechner verwenden, oder mindestens die Teile die zu langsam sind in einer anderen Programmiersprache schreiben. Wenn man anfängt Teile des Programms aus Geschwindigkeitsgründen komplizierter und schwerer verständlich auszudrücken als man das mit idiomatischem Python machen würde, oder gar anfängt deswegen Sprachelemente für Sachen zu missbrauchen für die sie nicht gedacht sind, macht man etwas falsch.

Re: Python: Schleifen iterierung Varianten

Verfasst: Samstag 12. Oktober 2019, 20:58
von /me
Zur Frage "macht es einen Unterschied?" kann man sich ja einfach mal den generierten Bytecode anschauen.

Code: Alles auswählen

def do_something(data):
    for record in data:
        print(record)
liefert

Code: Alles auswählen

  2           0 SETUP_LOOP              20 (to 22)
              2 LOAD_FAST                0 (data)
              4 GET_ITER
        >>    6 FOR_ITER                12 (to 20)
              8 STORE_FAST               1 (record)

  3          10 LOAD_GLOBAL              0 (print)
             12 LOAD_FAST                1 (record)
             14 CALL_FUNCTION            1
             16 POP_TOP
             18 JUMP_ABSOLUTE            6
        >>   20 POP_BLOCK
        >>   22 LOAD_CONST               0 (None)
             24 RETURN_VALUE

Code: Alles auswählen

def do_something(data):
    for i in range(len(data)):
        print(data[i])
führt zu

Code: Alles auswählen

  2           0 SETUP_LOOP              32 (to 34)
              2 LOAD_GLOBAL              0 (range)
              4 LOAD_GLOBAL              1 (len)
              6 LOAD_FAST                0 (data)
              8 CALL_FUNCTION            1
             10 CALL_FUNCTION            1
             12 GET_ITER
        >>   14 FOR_ITER                16 (to 32)
             16 STORE_FAST               1 (i)

  3          18 LOAD_GLOBAL              2 (print)
             20 LOAD_FAST                0 (data)
             22 LOAD_FAST                1 (i)
             24 BINARY_SUBSCR
             26 CALL_FUNCTION            1
             28 POP_TOP
             30 JUMP_ABSOLUTE           14
        >>   32 POP_BLOCK
        >>   34 LOAD_CONST               0 (None)
             36 RETURN_VALUE
Man muss den Bytecode nicht mal wirklich komplett verstehen um zu sehen, dass die zweite Variante im Resultat irgendwie aufgeblähter aussieht.

Re: Python: Schleifen iterierung Varianten

Verfasst: Samstag 12. Oktober 2019, 21:40
von snafu
Chaostheorie hat geschrieben: Freitag 11. Oktober 2019, 21:21 Ich arbeite seit kürzerem mit einem großen Dataset und wollte aufgrund meines schwächelnden PS's vorallem bei Schleifen durch list comprehensions Zeit sparen aber ich frage mich welche der Bieden oben genannten Varianten besser währe.
Keine der beiden Varianten ist eine List Comprehension. Es handelt sich im Falle von Python immer um for-each-Schleifen, d.h. die Elemente werden beim Schleifendurchlauf direkt geliefert. Im Gegensatz zur klassischen for-Schleife muss man die also nicht mehr per Indexzugriff ansprechen. Bei deiner "Simulation" der klassischen Schleife nutzt du eine for-each-Schleife über die Rückgabe von range() und die gelieferten Zahlen für den anschließenden Indexzugriff. Das ist unnötig umständlich, zeitaufwändiger und schlechter zu lesen. Daher besser gar nicht erst angewöhnen.

Zum Thema List Comprehensions findest du hier übrigens einige Infos auf deutsch:
https://py-tutorial-de.readthedocs.io/d ... rehensions

Ach ja, und für die Analyse und Manipulation größerer Datensätze eignet sich das externe Paket pandas recht gut. Das erleichtert vieles und ist - zumindest für numerische Daten - ziemlich flott, wenn man es richtig benutzt.

Re: Python: Schleifen iterierung Varianten

Verfasst: Samstag 12. Oktober 2019, 21:54
von DasIch
Ich würde empfehlen bei größeren Daten Mengen mal einen Blick auf pandas zu werfen. Wir haben da sehr gute Erfahrungen damit gesammelt um Daten im ein- bis zweistelligen GiB Bereich zu verarbeiten.