Flerdimensjonelle lister


Opprette 2D-lister og indeksering
# opprett en 2D-liste med gitte verdier (statisk opprettelse)
a = [[2, 3, 4], [5, 6, 7]]
print(a)
print(a[0])     # Første elment i a er en vanlig 1D-liste
print(a[0][1])  # Andre element (index 1) i første element i a
# MISLYKKET forsøkt på å opprette 2D-liste med dynamisk størrelse
rows = 3
cols = 2

a = [[0] * cols] * rows # Oppretter en "grunn" kopi
                        # Oppretter én unik rad, resten er aliaser

print("Dette VIRKER SOM det er ok.  I begynnelsen:")
print("   a =", a)

a[0][0] = 42
print("MEN, hva skjer etter at vi muterer a[0][0]=42?")
print("   a =", a)
# RIKTIG måte å opprette en 2D-liste med dynamisk størrelse
rows = 3
cols = 2

a = []
for _ in range(rows):
    a.append([0] * cols)

print("Dette ER ok.  I begynnelsen:")
print("   a =", a)

a[0][0] = 42
print("Etter at vi muterer a[0][0]=42")
print("   a =", a)
# Alternativ RIKTIG måte å opprette en 2D-liste med dynamisk størrelse
# Her benytter vi listeforståelse
rows = 3
cols = 2

a = [[0] * cols for _ in range(rows)]

print("Dette ER ok.  I begynnelsen:")
print("   a =", a)

a[0][0] = 42
print("Etter at vi muterer a[0][0]=42")
print("   a =", a)
Dimensjonene til en 2D-liste

En 2D-liste er en liste av lister. Selv om det ikke er påkrevd fra Python sin side, er det vanlig at alle de “innerste” listene er like lange. På den måten representerer 2D-listen et rutenett eller et regneark. Vi tenker oss at hver av de innerste listene representerer én rad, mens den ytterste listen inneholder alle radene.

# Anta at a er en hvilken som helst 2D-liste som representerer et rutenett
a = [[2, 3, 5], [1, 4, 7]]
print("a = ", a)

# La oss finne dimensjonene til rutenettet
rows = len(a)
cols = len(a[0])
print("rows =", rows)
print("cols =", cols)
Grunne og dype kopier

Først, et mislykket forsøk på å kopiere en 2D-liste. Du vil (dessverre) få samme oppførsel uansett hvilken variant av kopiering fra kursnotatene om 1D-lister du bruker.

# MISLYKKET forsøk på å kopiere en 2D-liste
import copy
a = [[1, 2, 3], [4, 5, 6]]

b = copy.copy(a) # Fra kursnotatene om 1D-lister

print("Dette VIRKER SOM det er ok.  I begynnelsen:")
print("   a =", a)
print("   b =", b)

a[0][0] = 42
print("MEN, hva skjer etter at vi muterer a[0][0]=42?")
print("   a =", a)
print("   b =", b)
# RIKTIG måte å kopiere en 2D-liste
import copy
a = [[1, 2, 3], [4, 5, 6]]

b = copy.deepcopy(a)

print("Dette ER er ok.  I begynnelsen:")
print("   a =", a)
print("   b =", b)

a[0][0] = 42
print("Etter at vi muterer a[0][0]=42")
print("   a =", a)
print("   b =", b)
Løkker over 2D-lister
# Anta at a er en hvilken som helst 2D-liste som representerer et rutenett
a = [[2, 3, 5], [1, 4, 7]]
print("Først: a =", a)

# Vi finner dimensjonene til rutenettet
rows = len(a)
cols = len(a[0])

# En løkke over hvert element i listen
# I eksempelet under øker vi verdien til hver celle i rutenettet med 1
for row in range(rows):
    for col in range(cols):
        # Koden her inne kjøres rows*cols ganger, én gang for hver
        # kombinasjon av verdier for row og col.
        a[row][col] += 1

# Til slutt, utskrift av resultatet
print("Etter:  a =", a)
Hente ut rader og kolonner

Få tilgang til en hel rad.

# Et alias, ikke en kopi! Ingen ny liste opprettes!
a = [[2, 3, 5], [1, 4, 7]]
row = 1
row_list = a[row]
print(row_list)

Få tilgang til en hel kolonne.

# IKKE et alias, men en kopi! Ny liste opprettes!
a = [[2, 3, 5], [1, 4, 7]]
col = 1
col_list = [] 
for row in range(len(a)):
    col_list.append(a[row][col])
print(col_list)

Få tilgang til en hel kolonne med listeforståelse.

# IKKE et alias, men en kopi! Ny liste opprettes!
a = [[2, 3, 5], [1, 4, 7]]
col = 1
col_list = [a[row][col] for row in range(len(a))]
print(col_list)
3D-lister

En 2D-liste er bare en liste av lister. Det er selvsagt mulig å ha en liste av 2D-lister. Dette blir da en 3D-liste. En liste med 3D-lister blir en 4D-liste, og så videre.

a = [
        [
            [1, 2],
            [3, 4],
        ],
        [
            [5, 6, 7],
            [8, 9],
        ],
        [
            [10],
        ],
    ]

for i in range(len(a)):
    for j in range(len(a[i])):
        for k in range(len(a[i][j])):
            print(f'a[{i}][{j}][{k}] = {a[i][j][k]}')