Próbowałem utworzyć listę 2D w Pythonie, który wynosił X + 1, Y + 1 wielkości i miał kilka wartości początkowych. Te wartości początkowe są takie, że pierwszy wiersz zawiera liczby 0 do "x", a pierwsza kolumna zawiera liczby 0 do "Y" (zarówno włącznie)

Powiedzmy, że X i Y były 3 i 4.

Więc poszedłem: listę = [zakres (0, x + 1)] * (y + 1);

Daje mi to listę 2D, która ma 5 wierszy, a każdy wiersz jest listą z liczbami 0 do 3 dając 4 indeksy na każdym rzędzie (4 kolumny):

[[0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3]]

Rozumiem, że w tym momencie mam tablicę 2D, ale każdy wiersz jest instancją, więc jeśli zmieniłem dowolną wartość w każdym rzędzie, wszystkie rzędy odzwierciedlałyby tę zmianę. Aby naprawić, że zdecydowałem się ustawić każdy wiersz na nową wyjątkową listę:

for row in listName:
    row = range(0, x + 1);

Ale zauważyłem, że wydaje się, że nie ma efektu, moja oryginalna lista, nawet jeśli poszedłem:

for row in listName:
    row = ["A", "B", "C", "D"];

Drukowanie przed i po wyświetleniu przypisania "wiersz" jest zmieniony, ale poza pętlą, dostaję moją oryginalną listę, gdy go wydrukuję. Nawet jeśli znalazłem inny sposób na zrobienie tego, czego chcę, nie mogę się dowiedzieć, dlaczego tak się dzieje. Jakieś pomysły?

2
mitim 8 grudzień 2011, 07:20

3 odpowiedzi

Najlepsza odpowiedź

Slice-przypisuj, aby zmodyfikować istniejącą listę, zamiast tylko rebindować nazwę.

row[:] = ...

Budujesz również nieprawidłowo.

listName = [range(0, x + 1) for z in range(y + 1)]
1
Ignacio Vazquez-Abrams 8 grudzień 2011, 03:26

Po przypisaniu listy do nazwy skutecznie tworzysz nową listę. Python ma specjalną składnię, która pozwala to zrobić:

row[:] = …

>>> listName = [range(0, x + 1)] * (y + 1);
>>> listName
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
>>> for row in listName:
...     row[:] = range(0, x+1)
... 
>>> listName
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
>>> for row in listName:
...     row[:] = range(0, x+6)
... 
>>> listName
[[0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8]]

Ale w oparciu o oryginalne pytanie, chciałeś to zrobić?

>>> [range(0, x+1)] + [[i] + [0]*x for i in xrange(1, y+1)]
[[0, 1, 2, 3], [1, 0, 0, 0], [2, 0, 0, 0], [3, 0, 0, 0], [4, 0, 0, 0]]
0
kojiro 8 grudzień 2011, 03:32

Ale zauważyłem, że wydaje się, że nie ma efektu, moja oryginalna lista

Ponieważ row = range(0, x + 1) nie oznacza "zawartości rzeczy, które row odnosi się do zastąpienia zawartością listy range(0, x + 1)"; Oznacza to "nazwa row powinna przestać odnosić się do tego, do czego obecnie odnosi się, a zamiast tego odnoszą się do listy range(0, x + 1)".

0
Karl Knechtel 8 grudzień 2011, 03:37