Как определить двумерный массив в Python - PullRequest
623 голосов
/ 12 июля 2011

Я хочу определить двумерный массив без инициализированной длины следующим образом:

Matrix = [][]

но это не работает ...

Я пробовал код ниже, но он тоже неправильный:

Matrix = [5][5]

Ошибка:

Traceback ...

IndexError: list index out of range

В чем моя ошибка?

Ответы [ 25 ]

891 голосов
/ 12 июля 2011

Технически вы пытаетесь проиндексировать неинициализированный массив. Вы должны сначала инициализировать внешний список списками, прежде чем добавлять элементы; Python называет это "понимание списка".

# Creates a list containing 5 lists, each of 8 items, all set to 0
w, h = 8, 5;
Matrix = [[0 for x in range(w)] for y in range(h)] 

Теперь вы можете добавлять элементы в список:

Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range... 
Matrix[0][6] = 3 # valid

print Matrix[0][0] # prints 1
x, y = 0, 6 
print Matrix[x][y] # prints 3; be careful with indexing! 

Хотя вы можете называть их по своему желанию, я смотрю на это так, чтобы избежать путаницы, которая может возникнуть при индексации, если вы используете «x» для внутреннего и внешнего списков и хотите использовать неквадратную матрицу .

361 голосов
/ 12 июля 2011

Если вы действительно хотите матрицу, вам лучше использовать numpy.Матричные операции в numpy чаще всего используют тип массива с двумя измерениями.Есть много способов создать новый массив;одна из наиболее полезных - это функция zeros, которая принимает параметр формы и возвращает массив заданной формы со значениями, инициализированными равными нулю:

>>> import numpy
>>> numpy.zeros((5, 5))
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

numpy обеспечивает matrixтипа также.Он используется реже, и некоторые люди рекомендуют против использовать его.Но это полезно для людей, приезжающих на numpy из Matlab, и в некоторых других контекстах.Я думал, что включу это, так как мы говорим о матрицах!

>>> numpy.matrix([[1, 2], [3, 4]])
matrix([[1, 2],
        [3, 4]])

Вот несколько других способов создания двумерных массивов и матриц (с выводом для компактности):

numpy.matrix('1 2; 3 4')                 # use Matlab-style syntax
numpy.arange(25).reshape((5, 5))         # create a 1-d range and reshape
numpy.array(range(25)).reshape((5, 5))   # pass a Python range and reshape
numpy.array([5] * 25).reshape((5, 5))    # pass a Python list and reshape
numpy.empty((5, 5))                      # allocate, but don't initialize
numpy.ones((5, 5))                       # initialize with ones
numpy.ndarray((5, 5))                    # use the low-level constructor
302 голосов
/ 12 июля 2011

Вот более короткая запись для инициализации списка списков:

matrix = [[0]*5 for i in range(5)]

К сожалению, сокращение этого до что-то вроде 5*[5*[0]] на самом деле не работает, потому что вы получаете 5 копий одного и того же списка, поэтому, когда вы изменяете одну из них, все они меняются, например:

>>> matrix = 5*[5*[0]]
>>> matrix
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> matrix[4][4] = 2
>>> matrix
[[0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2]]
95 голосов
/ 12 июля 2011

Если вы хотите создать пустую матрицу, правильный синтаксис будет

matrix = [[]]

А если вы хотите сгенерировать матрицу размера 5, заполненную 0,

matrix = [[0 for i in xrange(5)] for i in xrange(5)]
72 голосов
/ 29 мая 2014

Если вам нужен только двумерный контейнер для хранения некоторых элементов, вы можете вместо этого использовать словарь:

Matrix = {}

Тогда вы можете сделать:

Matrix[1,2] = 15
print Matrix[1,2]

Это работаетпотому что 1,2 - это кортеж, и вы используете его в качестве ключа для индексации словаря.Результат похож на тупую разреженную матрицу.

Как указано osa и Josap Valls, вы также можете использовать Matrix = collections.defaultdict(lambda:0), чтобы отсутствующие элементы имели значение по умолчанию 0.

Ватсал далее указывает, что этот метод, вероятно, не очень эффективен для больших матриц и должен использоваться только в не критичных для производительности частях кода.

37 голосов
/ 12 июля 2011

В Python вы будете создавать список списков. Вы не должны объявлять размеры заранее, но вы можете. Например:

matrix = []
matrix.append([])
matrix.append([])
matrix[0].append(2)
matrix[1].append(3)

Теперь matrix [0] [0] == 2 и matrix [1] [0] == 3. Вы также можете использовать синтаксис понимания списка. В этом примере он используется дважды для построения «двумерного списка»:

from itertools import count, takewhile
matrix = [[i for i in takewhile(lambda j: j < (k+1) * 10, count(k*10))] for k in range(10)]
19 голосов
/ 04 декабря 2015

Принятый ответ является правильным и правильным, но мне потребовалось некоторое время, чтобы понять, что я мог бы также использовать его для создания полностью пустого массива.

l =  [[] for _ in range(3)]

приводит к

[[], [], []]
18 голосов
/ 12 июля 2011

Вы должны составить список списков, и лучший способ - использовать вложенные понимания:

>>> matrix = [[0 for i in range(5)] for j in range(5)]
>>> pprint.pprint(matrix)
[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

В вашем примере [5][5] вы создаете список с целым числом "5" внутри и пытаетесь получить доступ к его 5-му элементу, что естественно вызывает ошибку IndexError, поскольку 5-го элемента нет:

>>> l = [5]
>>> l[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
14 голосов
/ 07 июля 2018
rows = int(input())
cols = int(input())

matrix = []
for i in range(rows):
  row = []
  for j in range(cols):
    row.append(0)
  matrix.append(row)

print(matrix)

Почему такой длинный код, который тоже в Python вы спрашиваете?

Давным-давно, когда я не чувствовал себя комфортно с Python, я видел однострочные ответы для написания 2D-матрицы и говорил себеЯ не собираюсь снова использовать 2-D матрицу в Python.(Эти отдельные строки были довольно страшными, и они не дали мне никакой информации о том, что делал Python. Также обратите внимание, что я не знаю об этих сокращениях.)

В любом случае, вот код для новичка, пришедшегоиз C, CPP и Java background

Примечание для любителей и экспертов Python: Пожалуйста, не отказывайтесь от голосования только потому, что я написал подробный код.

10 голосов
/ 08 декабря 2013

Чтобы объявить матрицу нулей (единиц):

numpy.zeros((x, y))

например,

>>> numpy.zeros((3, 5))
    array([[ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.]])

или numpy.ones ((x, y)), например,

>>> np.ones((3, 5))
array([[ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.]])

Возможны даже три измерения.(http://www.astro.ufl.edu/~warner/prog/python.html см. -> Многомерные массивы)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...