Как определить двумерный массив в Python
Я хочу определить двумерный массив без инициализированной длины, как это:
Matrix = [][]
но это не работает...
Я пробовал код ниже, но это тоже неправильно:
Matrix = [5][5]
ошибка:
Traceback ...
IndexError: list index out of range
в чем моя ошибка?
22 ответа:
вы технически пытаетесь индексировать неинициализированный массив. Вы должны сначала инициализировать внешний список со списками перед добавлением элементов; 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" как для внутреннего, так и для внешнего списков и хотите получить неквадратичную матрицу.
если вы действительно хотите матрицу, вам может быть лучше использовать
numpy
. Матричные операции вnumpy
чаще всего использовать тип массива с двумя измерениями. Есть много способов создать новый массив; одним из самых полезных являетсяzeros
функция, которая принимает параметр shape и возвращает массив заданной формы со значениями, инициализированными до нуля:>>> 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
вот более короткая нотация для инициализации списка списков:
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]]
Если вы хотите создать пустую матрицу, правильный синтаксис
matrix = [[]]
и если вы хотите создать матрицу размера 5, заполненную 0,
matrix = [[0 for i in xrange(5)] for i in xrange(5)]
если все, что вам нужно, это двухмерный контейнер для хранения некоторых элементов, вы можете удобно использовать словарь вместо этого:
Matrix = {}
затем вы можете сделать:
Matrix[1,2] = 15 print Matrix[1,2]
это работает, потому что
1,2
- кортеж, и вы используете его в качестве ключа для индексирования словаря. Результат похож на тупую разреженную матрицу.как указано osa и Josap Valls, вы также можете использовать
Matrix = collections.defaultdict(lambda:0)
Так что недостающие элементы имеют значение по умолчанию0
.Vatsal далее указывает, что этот метод, вероятно, не очень эффективен для больших матриц и должен использоваться только в некритических частях кода.
в Python вы будете создавать список списков. Вам не нужно объявлять размеры заранее, но вы можете. Например:
matrix = [] matrix.append([]) matrix.append([]) matrix[0].append(2) matrix[1].append(3)
теперь матрица[0][0] == 2 и матрица[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)]
принятый ответ хороший и правильный, но мне потребовалось некоторое время, чтобы понять, что я также могу использовать его для создания полностью пустого массива.
l = [[] for _ in range(3)]
результаты
[[], [], []]
вы должны составить список списков, и лучший способ - использовать вложенные понимания:
>>> 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]]
на
>>> l = [5] >>> l[5] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
чтобы объявить матрицу нулей (единиц):
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.одни ((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 см. -- > многомерные массивы)
переписать для удобства чтения:
# 2D array/ matrix # 5 rows, 5 cols rows_count = 5 cols_count = 5 # create # creation looks reverse # create an array of "cols_count" cols, for each of the "rows_count" rows # all elements are initialized to 0 two_d_array = [[0 for j in range(cols_count)] for i in range(rows_count)] # index is from 0 to 4 # for both rows & cols # since 5 rows, 5 cols # use two_d_array[0][0] = 1 print two_d_array[0][0] # prints 1 # 1st row, 1st col (top-left element of matrix) two_d_array[1][0] = 2 print two_d_array[1][0] # prints 2 # 2nd row, 1st col two_d_array[1][4] = 3 print two_d_array[1][4] # prints 3 # 2nd row, last col two_d_array[4][4] = 4 print two_d_array[4][4] # prints 4 # last row, last col (right, bottom element of matrix)
Я нахожусь на моем первом скрипте Python, и я был немного смущен примером квадратной матрицы, поэтому я надеюсь, что приведенный ниже пример поможет вам сэкономить время:
# Creates a 2 x 5 matrix Matrix = [[0 for y in xrange(5)] for x in xrange(2)]
, Так что
Matrix[1][4] = 2 # Valid Matrix[4][1] = 3 # IndexError: list index out of range
использование:
matrix = [[0]*5 for i in range(5)]
*5 для первого измерения работает, потому что на этом уровне данные неизменяемы.
С помощью NumPy вы можете инициализировать пустую матрицу следующим образом:
import numpy as np mm = np.matrix([])
и позже добавить данные, как это:
mm = np.append(mm, [[1,2]], axis=1)
Я читаю в файлах, разделенных запятыми, как это:
data=[] for l in infile: l = split(',') data.append(l)
список "данные" - это список списков с индексными данными[row][col]
# Creates a list containing 5 lists initialized to 0 Matrix = [[0]*5]*5
будьте осторожны с этим коротким выражением, см. полное объяснение в ответе @F. J
использование:
import copy def ndlist(*args, init=0): dp = init for x in reversed(args): dp = [copy.deepcopy(dp) for _ in range(x)] return dp l = ndlist(1,2,3,4) # 4 dimensional list initialized with 0's l[0][1][2][3] = 1
Я действительно думаю, что NumPy-это путь. Выше приведен общий, если вы не хотите использовать NumPy.
что это словарь сделано для!
matrix = {}
вы можете определить ключи и значения двумя способами:
matrix[0,0] = value
или
matrix = { (0,0) : value }
результат:
[ value, value, value, value, value], [ value, value, value, value, value], ...
Если вы хотите думать об этом как о 2D массиве, а не о том, чтобы думать в терминах списка списков (на мой взгляд, гораздо более естественно), вы можете сделать следующее:
import numpy Nx=3; Ny=4 my2Dlist= numpy.zeros((Nx,Ny)).tolist()
результатом является список (а не массив NumPy), и вы можете перезаписать отдельные позиции числами, строками, чем угодно.
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 в фоне
Примечание Для любителей Python и экспертов: пожалуйста, не голосуйте просто потому, что я написал подробный код.
Если у вас нет информации о размере перед запуском, то создайте два одномерных списка.
список 1: для хранения строк список 2: фактическая двумерная матрица
сохранить всю строку в 1-м списке. После этого добавьте список 1 в список 2:
from random import randint coordinates=[] temp=[] points=int(raw_input("Enter No Of Coordinates >")) for i in range(0,points): randomx=randint(0,1000) randomy=randint(0,1000) temp=[] temp.append(randomx) temp.append(randomy) coordinates.append(temp) print coordinates
выход:
Enter No Of Coordinates >4 [[522, 96], [378, 276], [349, 741], [238, 439]]
С помощью списка :
matrix_in_python = [['Roy',80,75,85,90,95],['John',75,80,75,85,100],['Dave',80,80,80,90,95]]
С помощью dict: вы также можете сохранить эту информацию в хэш-таблице для быстрого поиска, как
matrix = { '1':[0,0] , '2':[0,1],'3':[0,2],'4' : [1,0],'5':[1,1],'6':[1,2],'7':[2,0],'8':[2,1],'9':[2,2]};
матрица ['1'] даст вам результат в O(1) раз
* nb: вам нужно иметь дело с коллизией в хэш-таблице