Jak zainicjować tablicę dwuwymiarową w Pythonie?

Zaczynam Pythona i próbuję użyć dwuwymiarowej listy, którą początkowo wypełniam tą samą zmienną w każdym miejscu. Wymyśliłem to:

def initialize_twodlist(foo):
    twod_list = []
    new = []
    for i in range (0, 10):
        for j in range (0, 10):
            new.append(foo)
        twod_list.append(new)
        new = []

Daje pożądany rezultat, ale czuje się jak obejście. Czy istnieje na to łatwiejszy/krótszy/bardziej elegancki sposób?

Author: Alex Martelli, 2010-03-07

20 answers

Wzór, który często pojawiał się w Pythonie to

bar = []
for item in some_iterable:
    bar.append(SOME EXPRESSION)

Co pomogło zmotywować wprowadzenie list compensions, które konwertują ten fragment do

bar = [SOME EXPRESSION for item in some_iterable]
Która jest krótsza, a czasem wyraźniejsza. Zwykle masz w zwyczaju rozpoznawać je i często zastępować pętle składaniem.

Twój kod podąża za tym wzorcem dwa razy

twod_list = []                                       \                      
for i in range (0, 10):                               \
    new = []                  \ can be replaced        } this too
    for j in range (0, 10):    } with a list          /
        new.append(foo)       / comprehension        /
    twod_list.append(new)                           /
 308
Author: Mike Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-07 17:43:11

Możesz użyć listy :

x = [[foo for i in range(10)] for j in range(10)]
# x is now a 10x10 array of 'foo' (which can depend on i and j if you want)
 165
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-07 17:30:38

Ten sposób jest szybszy niż zagnieżdżone składanie list

[x[:] for x in [[foo] * 10] * 10]    # for immutable foo!
Oto kilka terminów python3, dla małych i dużych list
$python3 -m timeit '[x[:] for x in [[1] * 10] * 10]'
1000000 loops, best of 3: 1.55 usec per loop

$ python3 -m timeit '[[1 for i in range(10)] for j in range(10)]'
100000 loops, best of 3: 6.44 usec per loop

$ python3 -m timeit '[x[:] for x in [[1] * 1000] * 1000]'
100 loops, best of 3: 5.5 msec per loop

$ python3 -m timeit '[[1 for i in range(1000)] for j in range(1000)]'
10 loops, best of 3: 27 msec per loop

Wyjaśnienie:

[[foo]*10]*10 tworzy listę tego samego obiektu powtórzoną 10 razy. Nie możesz tego po prostu użyć, ponieważ modyfikowanie jednego elementu zmieni ten sam element w każdym wierszu!

x[:] jest odpowiednikiem list(X), ale jest nieco bardziej wydajny, ponieważ unika wyszukiwania nazwy. Tak czy inaczej, tworzy płytką kopię każdy wiersz, więc teraz wszystkie elementy są niezależne.

Wszystkie elementy są tym samym obiektem foo, więc jeśli foo jest zmienny , nie można używać tego schematu., musisz użyć

import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]

Lub zakładając klasę (lub funkcję) Foo, która zwraca foo s

[[Foo() for x in range(10)] for y in range(10)]
 115
Author: John La Rooy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-28 01:38:31

Inicjalizacja tablicy dwuwymiarowej w Pythonie:

a = [[0 for x in range(columns)] for y in range(rows)]
 43
Author: Vipul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-14 06:17:23

Nie używaj [[v]*n]*n, to pułapka!

>>> a = [[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]=1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

Ale t = [[0]*3 dla i w zakresie (3)] is great

 37
Author: Jason CHAN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 23:03:54
[[foo for x in xrange(10)] for y in xrange(10)]
 23
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-07 17:29:40

Zazwyczaj, gdy chcesz tablic wielowymiarowych, nie chcesz listy list, ale raczej tablicy numpy lub ewentualnie dict.

Na przykład, z numpy można zrobić coś takiego

import numpy
a = numpy.empty((10, 10))
a.fill(foo)
 20
Author: Mike Graham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-07 17:36:05

Możesz zrobić tylko to:

[[element] * numcols] * numrows

Na przykład:

>>> [['a'] *3] * 2
[['a', 'a', 'a'], ['a', 'a', 'a']]

Ale to ma niepożądane skutki uboczne:

>>> b = [['a']*3]*3
>>> b
[['a', 'a', 'a'], ['a', 'a', 'a'], ['a', 'a', 'a']]
>>> b[1][1]
'a'
>>> b[1][1] = 'b'
>>> b
[['a', 'b', 'a'], ['a', 'b', 'a'], ['a', 'b', 'a']]
 12
Author: hithwen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-01 11:27:36

Jeśli jest to słabo zaludniona tablica, lepiej będzie użyć słownika z kluczem krotki:

dict = {}
key = (a,b)
dict[key] = value
...
 7
Author: btk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-02 21:11:54

Użyj najprostszego myślenia, aby to stworzyć.

wtod_list = []

I dodaj rozmiar:

wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]

Lub jeśli chcemy najpierw zadeklarować rozmiar. używamy tylko:

   wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]
 3
Author: indi60,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-18 07:05:09

Nieprawidłowe podejście: [[None * m] * n]

>>> m, n = map(int, raw_input().split())
5 5
>>> x[0][0] = 34
>>> x
[[34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None], [34, None, None, None, None]]
>>> id(x[0][0])
140416461589776
>>> id(x[3][0])
140416461589776

Dzięki temu podejściu python nie pozwala na tworzenie innej przestrzeni adresowej dla zewnętrznych kolumn i prowadzi do różnych niewłaściwych zachowań niż oczekiwano.

Poprawne podejście, ale z wyjątkiem:

y = [[0 for i in range(m)] for j in range(n)]
>>> id(y[0][0]) == id(y[1][0])
False

Jest to dobre podejście, ale istnieje wyjątek, jeśli ustawisz wartość domyślną na None

>>> r = [[None for i in range(5)] for j in range(5)]
>>> r
[[None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None], [None, None, None, None, None]]
>>> id(r[0][0]) == id(r[2][0])
True

Więc ustaw wartość domyślną poprawnie, używając tego podejścia.

Absolutna poprawność:

Follow the mike ' s odpowiedź podwójna pętla.

 3
Author: patilnitin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-17 01:46:48
t = [ [0]*10 for i in [0]*10]

Dla każdego elementu zostanie utworzony Nowy [0]*10..

 3
Author: user9269722,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 21:30:44

Jak zauważyli @Arnab i @ Mike, tablica nie jest listą. Niewiele różnic to 1) tablice mają stały rozmiar podczas inicjalizacji 2) tablice Zwykle obsługują mniejsze operacje niż lista.

Może to przesada w większości przypadków, ale oto podstawowa implementacja macierzy 2D, która wykorzystuje implementację macierzy sprzętowej przy użyciu Pythona ctypes (biblioteki c)

import ctypes
class Array:
    def __init__(self,size,foo): #foo is the initial value
        self._size = size
        ArrayType = ctypes.py_object * size
        self._array = ArrayType()
        for i in range(size):
            self._array[i] = foo
    def __getitem__(self,index):
        return self._array[index]
    def __setitem__(self,index,value):
        self._array[index] = value
    def __len__(self):
        return self._size

class TwoDArray:
    def __init__(self,columns,rows,foo):
        self._2dArray = Array(rows,foo)
        for i in range(rows):
            self._2dArray[i] = Array(columns,foo)

    def numRows(self):
        return len(self._2dArray)
    def numCols(self):
        return len((self._2dArray)[0])
    def __getitem__(self,indexTuple):
        row = indexTuple[0]
        col = indexTuple[1]
        assert row >= 0 and row < self.numRows() \
               and col >=0 and col < self.numCols(),\
               "Array script out of range"
        return ((self._2dArray)[row])[col]

if(__name__ == "__main__"):
    twodArray = TwoDArray(4,5,5)#sample input
    print(twodArray[2,3])
 1
Author: Antony Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 19:45:18
Matrix={}
for i in range(0,3):
  for j in range(0,3):
    Matrix[i,j] = raw_input("Enter the matrix:")
 1
Author: Sparsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 16:50:29
twod_list = [[foo for _ in range(m)] for _ in range(n)]

Dla n jest liczbą wierszy, A m jest liczbą kolumn, a foo jest wartością.

 1
Author: Moustafa Saleh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-03 02:30:14

Jest to najlepszy, jaki znalazłem do nauczania nowych programistów i bez używania dodatkowych bibliotek. Chciałbym coś lepszego.

def initialize_twodlist(value):
    list=[]
    for row in range(10):
        list.append([value]*10)
    return list
 0
Author: Paul Vincent Craven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 15:33:00

Oto łatwiejszy sposób:

import numpy as np
twoD = np.array([[]*m]*n)

Do inicjalizacji wszystkich komórek z dowolną wartością' x ' Użyj :

twoD = np.array([[x]*m]*n
 0
Author: user3650331,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 18:23:25

Często używam tego podejścia do inicjalizacji tablicy 2-wymiarowej

n=[[int(x) for x in input().split()] for i in range(int(input())]

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-18 07:49:04

Ogólny wzór dodawania wymiarów można narysować z tej serii:

x = 0
mat1 = []
for i in range(3):
    mat1.append(x)
    x+=1
print(mat1)


x=0
mat2 = []
for i in range(3):
    tmp = []
    for j in range(4):
        tmp.append(x)
        x+=1
    mat2.append(tmp)

print(mat2)


x=0
mat3 = []
for i in range(3):
    tmp = []
    for j in range(4):
        tmp2 = []
        for k in range(5):
            tmp2.append(x)
            x+=1
        tmp.append(tmp2)
    mat3.append(tmp)

print(mat3)
 0
Author: juanfal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-16 16:21:19
from random import randint
l = []

for i in range(10):
    k=[]
    for j in range(10):
        a= randint(1,100)
        k.append(a)

    l.append(k)




print(l)
print(max(l[2]))

b = []
for i in range(10):
    a = l[i][5]
    b.append(a)

print(min(b))
 -2
Author: KANDARP JAYESH SHAH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 22:43:20