Seite 1 von 1

list.append() - eigenartiges Verhalten

Verfasst: Mittwoch 23. Oktober 2019, 10:54
von Fel
Hallo,
ich möchte alle Kombinationen aus 0 und 1 in einer 2x2 list generieren und habe dazu schnell ein paar Zeilen in Python 2.7 geschrieben:

Code: Alles auswählen

kombi = [[0,0],[0,0]]
kombinationen = []

for i in range(2):
    kombi[0][0] = i
    for j in range(2):
        kombi[0][1] = j
        for k in range(2):
            kombi[1][1] = k
            for l in range(2):
                kombi[1][0] = l
                print kombi
                kombinationen.append(kombi)
print 'Kombinationen:', kombinationen
Interessanterweise ist das hier der Output:

Code: Alles auswählen

[[0, 0], [0, 0]]
[[0, 0], [1, 0]]
[[0, 0], [0, 1]]
[[0, 0], [1, 1]]
[[0, 1], [0, 0]]
[[0, 1], [1, 0]]
[[0, 1], [0, 1]]
[[0, 1], [1, 1]]
[[1, 0], [0, 0]]
[[1, 0], [1, 0]]
[[1, 0], [0, 1]]
[[1, 0], [1, 1]]
[[1, 1], [0, 0]]
[[1, 1], [1, 0]]
[[1, 1], [0, 1]]
[[1, 1], [1, 1]]
Kombinationen: [[[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]]
Warum sind alle Einträge der Liste 1??
Ich habe erstmal angenommen, dass es ein Deep-Copy Problem ist und habe stattdessen die Zeile

Code: Alles auswählen

kombinationen.append(kombi[:])
verwendet. Aber das löst das Problem ebenfalls nicht.
Wenn jemand eine Idee hat, wäre ich dankbar :)

Liebe Grüße,
Fel

Re: list.append() - eigenartiges Verhalten

Verfasst: Mittwoch 23. Oktober 2019, 11:51
von __deets__
Da du immer die gleiche Liste modifizierst, ist das kein Wunder. Und nicht nur das: kombi ist eine Liste, aber auch seine Eintraege sind Listen. Und *DIE* bleiben auch bei kombi[:] unveraendert.

Ganz generell macht man sowas so nicht. Man modifiziert keine bestehenden Datenstrukturen, die man dann eh kopieren muss. Man erzeugt einfach immer neue.

Gibt es einen Grund, warum du nicht einfach itertools.product benutzt?

Re: list.append() - eigenartiges Verhalten

Verfasst: Sonntag 27. Oktober 2019, 10:05
von __blackjack__
@Fel: Python 2 sollte man nicht mehr verwenden. Insbesondere für neuen Code.

Mit dem angesprochenen `itertools.product()` könnte eine Lösung so aussehen:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import product
from pprint import pprint


def main():
    bit_count = 4
    bits_per_row = bit_count // 2
    table = list()
    for bits in product([0, 1], repeat=bit_count):
        table.append([bits[:bits_per_row], bits[bits_per_row:]])
    pprint(table)


if __name__ == "__main__":
    main()]