List Magic
Head, Tail
Altes Problem, geht man zumeist so an:
>>> l = list(range(10))
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> head, tail = l[0], l[1:]
>>> head
0
>>> tail
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Nach PEP 3132 wird das alles viel eleganter:
>>> head, *tail = list(range(10))
>>> head
0
>>> tail
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Was noch so geht
Zum Beispiel beim Iterieren über eine Liste von Tupeln das letzte Element extra behandeln:
>>> l = list((x, x+x, x*x) for x in range(5))
>>> l
[(0, 0, 0), (1, 2, 1), (2, 4, 4), (3, 6, 9), (4, 8, 16)]
>>> for *head, last in l:
... print(last, '->', head)
...
0 -> [0, 0]
1 -> [1, 2]
4 -> [2, 4]
9 -> [3, 6]
16 -> [4, 8]
Flatten
Verschachtelte Listen lassen sich durch eine List-Comprehension auflösen:
>>> ll = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>> [fl for at in ll for fl in at]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Das ganze ist aber nicht Speichereffizient.
Wenn man über die Elemente in den Listen der Liste iterieren muss, greift man
auf die itertools
zurück:
>>> from itertools import chain
>>> ll = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>> cl = chain.from_iterable(ll)
>>> cl
<itertools.chain object at 0x10a8b5b00>
>>> for c in cl:
... print(c)
...
0
1
2
[...]
Achtung. Es handelt sich hier um einen Iterator. Wenn versucht wird mehrmals darüber zu iterieren, wird das nichts.
>>> ll = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>> cl = chain.from_iterable(ll)
>>> list(cl)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(cl)
[]
Verschachtelt iterieren
Das ganze lässt sich aber auch dazu nutzen, mehrere for-loops abzukürzen:
>>> res = []
>>> for x in [0, 1, 2, 3, 4]:
... for y in [5, 6, 7, 8, 9]:
... res.append((x, y, x+y, x*y))
>>> res
[(0, 5, 5, 0), (0, 6, 6, 0), (0, 7, 7, 0), ...]
… wird somit zu:
>>> nres = [(x, y, x+y, x*y) for x in [0, 1, 2, 3, 4] for y in [5, 6, 7, 8, 9]]
>>> nres
[(0, 5, 5, 0), (0, 6, 6, 0), (0, 7, 7, 0), ...]
>>> assert res == nres
last update: 2024-01-28 12:40:56 +0100