Woche 08#

zip()#

en: zipper, Reißverschluss

zahlen = [ 1, 2 , 3 ]
abc =  ['a', 'b', 'c']
aussprache = ['alpha', 'bravo', 'charlie' ]

Wir haben n gleichlange (!) Listen. list( zip() ) erzeugt daraus eine einzige Liste von n-Tupeln.

z = list(zip(zahlen, abc, aussprache))
z
[(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie')]

Falls n == 2 können wir auch ein Dict erzeugen:

z_dict = dict(zip(zahlen, abc))
z_dict
{1: 'a', 2: 'b', 3: 'c'}
z3 = list( zip( zahlen, abc, aussprache ))
z3
[(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie')]

starred#

Gibt es eine inverse Funktion “unzip”? JA!

Aber ganz spezielle Syntax; und nur einsetzbar in speziellen Situationen, z.B. bei Funktionen, die variabel viele Parameter zulassen. so eine Funktion kennen wir schon: print()!

z
[(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie')]
sep = " | "
print("alpha", z, "omega", sep=sep)
alpha | [(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie')] | omega
print("alpha", *z, "omega", sep=sep)
alpha | (1, 'a', 'alpha') | (2, 'b', 'bravo') | (3, 'c', 'charlie') | omega

Auch die Funktion zip() kann eine variable Anzahl von Parametern verstehen. Also können wir statt mehreren Parametern auch eine einzige Liste übergeben, die mehrere (gleichlange) Listen enthält, und diese Liste mit * auspacken.

matrix_spaltenweise = [ [ 1, 2 , 3, 4 ],
        ['a', 'b', 'c', 'd'],
        ['alpha', 'bravo', 'charlie', 'delta' ]
      ]
matrix_spaltenweise
[[1, 2, 3, 4], ['a', 'b', 'c', 'd'], ['alpha', 'bravo', 'charlie', 'delta']]
list( zip( matrix_spaltenweise[0], matrix_spaltenweise[1], matrix_spaltenweise[2] ) )  
[(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie'), (4, 'd', 'delta')]
matrix_zeilenweise = list( zip( *matrix_spaltenweise ))
matrix_zeilenweise
[(1, 'a', 'alpha'), (2, 'b', 'bravo'), (3, 'c', 'charlie'), (4, 'd', 'delta')]
matrix_spaltenweise_2 = list( zip( *matrix_zeilenweise ))
matrix_spaltenweise_2
[(1, 2, 3, 4), ('a', 'b', 'c', 'd'), ('alpha', 'bravo', 'charlie', 'delta')]

Fingerübung: zip selber programmieren#

Vor-Vorübung: Index vs. Slice

aussprache
['alpha', 'bravo', 'charlie']
# ohne Doppelmunkt: Index, wählt ein Element aus
aussprache[1]  # erstes Element hat Index 0!
'bravo'
# mit Doppelpunkt: Slice, wählt eine Liste aus
aussprache[1:2] # erster Index 'drinn, zweiter Index nicht mehr 
['bravo']

Vorübung, das kennen wir schon: Zwei Arten, durch eine Liste durchzugehen

# direktes Durchgehen
for x in aussprache:
    print(x)
alpha
bravo
charlie
# indirektes Durchgegen mit Index
for i in range( len(aussprache) ):
    print( aussprache[i] )
alpha
bravo
charlie
ad = { 'a': 'alpha', 'b': 'bravo', 'c': 'charlie'}
ad
{'a': 'alpha', 'b': 'bravo', 'c': 'charlie'}
# direktes Durchgehen
for k,v in ad.items():
    print(k, v, sep=": ")
a: alpha
b: bravo
c: charlie
# indirektes Durchgehen: k als key (ähnlich "index") verwenden
for k in ad.keys():
    print(k, ad[k], sep=": ")
a: alpha
b: bravo
c: charlie

Jetzt endlich die Übung ;-) Damit können wir nun unsere Funktion meinzip() leicht erzeugen:

def meinzip(a,b):

    ergebnis = []

    for i in range( len(a) ):
        #print( f"DEBUG 100: {i}" )
        ergebnis.append(  (a[i], b[i])  ) 

    
    return ergebnis
# ausführen
meinzip( zahlen, abc )
[(1, 'a'), (2, 'b'), (3, 'c')]
# Test
meinzip(zahlen, abc) == [(1, 'a'), (2, 'b'), (3, 'c')]
True
# noch ein Test, allgemeiner
meinzip(zahlen, abc) == list(zip(zahlen, abc))
True