Когда вы вызываете std::vector::resize(X)
, вы просите vector (по крайней мере, потенциально) создать X
объекты. Единственный способ, которым вектор может это сделать, - это построить их по умолчанию, потому что вы больше ничего не даете ему. А поскольку ваша структура не имеет конструктора по умолчанию, resize
не может быть скомпилирован.
И на всякий случай ваша структура не имеет конструктора по умолчанию, потому что вы объявили конструктор пользователя.
Можно создать его с помощью вложенных списков:
matrix = [[a,b],[c,d],[e,f]]
Если это должно быть динамично, это более сложно, почему бы не записать маленький класс самостоятельно?
class Matrix(object):
def __init__(self, rows, columns, default=0):
self.m = []
for i in range(rows):
self.m.append([default for j in range(columns)])
def __getitem__(self, index):
return self.m[index]
Это может использоваться как это:
m = Matrix(10,5)
m[3][6] = 7
print m[3][6] // -> 7
Я уверен, что мог реализовать его намного более эффективный.:)
При необходимости в многомерных массивах, можно или создать массив и вычислить смещение, или Вы использовали бы массивы в массивах в массивах, которые могут быть довольно плохими для памяти. (Могло быть быстрее, хотя …), я реализовал первую идею как это:
class Matrix(object):
def __init__(self, *dims):
self._shortcuts = [i for i in self._create_shortcuts(dims)]
self._li = [None] * (self._shortcuts.pop())
self._shortcuts.reverse()
def _create_shortcuts(self, dims):
dimList = list(dims)
dimList.reverse()
number = 1
yield 1
for i in dimList:
number *= i
yield number
def _flat_index(self, index):
if len(index) != len(self._shortcuts):
raise TypeError()
flatIndex = 0
for i, num in enumerate(index):
flatIndex += num * self._shortcuts[i]
return flatIndex
def __getitem__(self, index):
return self._li[self._flat_index(index)]
def __setitem__(self, index, value):
self._li[self._flat_index(index)] = value
Может использоваться как это:
m = Matrix(4,5,2,6)
m[2,3,1,3] = 'x'
m[2,3,1,3] // -> 'x'
Если Вы ограничиваете себя библиотекой стандарта Python, то список списков является самой близкой конструкцией:
arr = [[1,2],[3,4]]
дает как будто 2-й массив. К строкам можно получить доступ как arr[i]
для i
в {0,..,len(arr}
, но доступ столбца является трудным.
Если Вы готовы добавить зависимость библиотеки, пакет NumPy - то, что Вы действительно хотите. Можно создать массив фиксированной длины из списка использования списков:
import numpy
arr = numpy.array([[1,2],[3,4]])
Доступ столбца совпадает с для списка списков, но доступ столбца легок: arr[:,i]
для i
в {0,..,arr.shape[1]}
(число столбцов).
На самом деле массивы NumPy могут быть n-мерными.
Пустые массивы могут быть созданы с
numpy.empty(shape)
где shape
кортеж размера в каждом размере; shape=(1,3,2)
дает 3-й массив с размером 1 в первом размере, размер 3 во втором размере и 2 в 3-м размере.
Если Вы хотите хранить объекты в массиве NumPy, можно сделать это также:
arr = numpy.empty((1,), dtype=numpy.object)
arr[0] = 'abc'
Для большего количества информации о проекте NumPy проверьте домашнюю страницу NumPy.
Создать стандартный массив Python массивов произвольного размера:
a = [[0]*cols for _ in [0]*rows]
К этому получают доступ как это:
a[0][1] = 5 # set cell at row 0, col 1 to 5
Маленький глюк Python это стоит упомянуть: заманчиво просто ввести
a = [[0]*cols]*rows
но это скопирует тот же массив столбца в каждую строку, приводящую к нежелательному поведению. А именно:
>>> a[0][0] = 5
>>> print a[1][0]
5
Многомерные массивы немного темны. Существует немного причин использования их и многих причин размышления дважды и использования чего-то еще, что более правильно отражает то, что Вы делаете. [Подсказка. Ваш вопрос был тонким на контексте ;-)]
При выполнении матричной математики то используйте numpy
.
Однако некоторые люди работали с языками, которые вынуждают их использовать многомерные массивы, потому что это - все, что они имеют. Если Ваш столь же старый, как я (я начал программировать в 70-х) затем можно помнить дни, когда многомерные массивы были единственной структурой данных, Вы имели. Или, Ваш опыт, возможно, ограничил Вас языками, где необходимо было превратить проблему в многомерные массивы.
Скажите, что у Вас есть набор n 3D точки. Каждая точка имеет x, y, z, и временную стоимость. Действительно ли это - массив n x 4? Или 4 * n массив?Не совсем.
Так как каждая точка имеет 4 фиксированных значения, это - более правильно список кортежей.
a = [ ( x, y, z, t ), ( x, y, z, t ), ... ]
Лучше все еще мы могли представить это как список объектов.
class Point( object ):
def __init__( self, x, y, z, t ):
self.x, self.y, self.z, self.t = x, y, z, t
a = [ Point(x,y,x,t), Point(x,y,z,t), ... ]
Смотрите на numpy
вот фрагмент кода для Вас
import numpy as npy
d = npy.zeros((len(x)+1, len(y)+1, len(x)+len(y)+3))
d[0][0][0] = 0 # although this is unnecessary since zeros initialises to zero
d[i][j][k] = npy.inf
Я не думаю, что необходимо реализовывать научное приложение для выравнивания по ширине использования numpy. Это быстрее и более гибко, и можно сохранить в значительной степени что-либо. Учитывая, что я думаю, что, вероятно, лучше попытаться выровнять по ширине не использование его. Существуют законные причины, но это добавляет много и стоит очень мало так, это заслуживает рассмотрения.
P.S. Действительно ли Ваши длины массива являются правильными? Это похоже на матрицу довольно специфической формы...
Если Вы в порядке с помощью разреженных массивов, Вы могли бы использовать dict для хранения значений. dicts Python позволяют Вам использовать кортежи в качестве ключей, как таковых, Вы могли присвоиться к и элементы доступа "разреженного массива" (который является действительно dict здесь) как это:
d = {}
d[0,2,7] = 123 # assign 123 to x=0, y=2, z=7
v = d[0,2,7]
Вероятно, не важный для Вас, но если Вы делаете серьезную матричную работу, см. numpy
Другая опция состоит в том, чтобы использовать словарь:
>>> from collections import defaultdict
>>> array = defaultdict(int) # replace int with the default-factory you want
>>> array[(0,0)]
0
>>> array[(99,99)]
0
Необходимо будет отслеживать верхние и нижние границы также.
Вот быстрый способ создать вложенный 3-мерный список, инициализированный с нулями:
# dim1, dim2, dim3 are the dimensions of the array
a =[[[0 for _ in range(dim1)] for _ in range(dim2)] for _ in range(dim1) ]
a[0][0][0] = 1
это - список списков списков, немного более гибких, чем массив, можно сделать:
a[0][0] = [1,2,3,4]
заменить целую строку в массиве или даже злоупотребить им как этот:
a[0] = "Ouch"
print a[0][0] #will print "O", since strings are indexable the same way as lists
print a[0][0][0] #will raise an error, since "O" isn't indexable
но если Вам нужна производительность, затем я соглашаюсь, что numpy является способом пойти.
Кроме того, остерегайтесь:
a = [[[0] * 5]*5]*5]
Если Вы пробуете a[0][0][0]=7
на объекте выше, Вы будете видеть что случилось с этим.
Для числовых данных, Массивов Numpy:
>>> matrix1 = array(([0,1],[1,3]))
>>> print matrix1
[[0 1]
[1 3]]
Для общих данных (например, строки), можно использовать список списков, списка кортежей...
matrix2 = [['a','b'], ['x','y']]
Я только что столкнулся с аналогичной потребностью и написал это:
def nDimensionsMatrix(dims, elem_count, ptr=[]):
if (dims > 1):
for i in range(elem_count[dims-1]):
empty = []
ptr.append(empty)
nDimensionsMatrix(dims-1, elem_count, empty)
return ptr
elif dims == 1:
ptr.extend([0 for i in range(elem_count[dims])])
return ptr
matrix = nDimensionsMatrix(3, (2,2,2))
Я не смотрю на скорость, а только на функциональность;)
Я хочу создать матрицу с N измерениями и инициализировать с помощью 0 ( elem_count количество элементов в каждом измерении).
Надеюсь, это поможет кому-то
Легко, при использовании numpy:
b = ones((2,3,4)) # creates a 2x3x4 array containing all ones.
«единицы» можно заменить на «нули»