Как инициализировать двумерный массив в Python?
Я начинаю python, и я пытаюсь использовать двумерный список, который я изначально заполняю одной переменной во всех местах. Я придумал это:
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 = []
Он дает желаемый результат, но выглядит как обходной путь. Есть ли более простой/более короткий/более элегантный способ сделать это?
Ответы
Ответ 1
Шаблон, который часто возникал в Python, был
bar = []
for item in some_iterable:
bar.append(SOME EXPRESSION)
которые помогли мотивировать введение перечня списков, которые преобразуют этот фрагмент в
bar = [SOME EXPRESSION for item in some_iterable]
который короче, а иногда и яснее. Обычно вы привыкаете распознавать их и часто заменяете петли пониманием.
Ваш код следует за этим шаблоном дважды
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) /
Ответ 2
Вы можете использовать понимание :
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)
Ответ 3
Этот способ быстрее, чем вложенные списки.
[x[:] for x in [[foo] * 10] * 10] # for immutable foo!
Ниже приведены некоторые тайминги python3 для небольших и больших списков
$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
Пояснение:
[[foo]*10]*10
создает список того же объекта, который повторяется 10 раз. Вы не можете просто использовать это, потому что изменение одного элемента будет изменять тот же самый элемент в каждой строке!
x[:]
эквивалентен list(X)
, но является более эффективным, поскольку он позволяет избежать поиска по имени. В любом случае, он создает неглубокую копию каждой строки, поэтому теперь все элементы независимы.
Все элементы - это один и тот же объект foo
, хотя, если foo
изменен, вы не можете использовать эту схему. Вам нужно будет использовать
import copy
[[copy.deepcopy(foo) for x in range(10)] for y in range(10)]
или предполагая класс (или функцию) foo
, который возвращает foo
s
[[Foo() for x in range(10)] for y in range(10)]
Ответ 4
Не используйте [[v] * n] * n, это ловушка!
>>> 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]]
но
t = [[0] * 3 для i в диапазоне (3)]
отлично
Ответ 5
Чтобы инициализировать двумерный массив в Python:
a = [[0 for x in range(columns)] for y in range(rows)]
Ответ 6
[[foo for x in xrange(10)] for y in xrange(10)]
Ответ 7
Обычно, когда вам нужны многомерные массивы, вам не нужен список списков, а скорее массив с числами или, возможно, dict.
Например, с numpy вы бы сделали что-то вроде
import numpy
a = numpy.empty((10, 10))
a.fill(foo)
Ответ 8
Вы можете сделать только это:
[[element] * numcols] * numrows
Например:
>>> [['a'] *3] * 2
[['a', 'a', 'a'], ['a', 'a', 'a']]
Но это имеет нежелательный побочный эффект:
>>> 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']]
Ответ 9
Если это малонаселенный массив, вам может быть лучше использовать словарь с ключом:
dict = {}
key = (a,b)
dict[key] = value
...
Ответ 10
twod_list = [[foo for _ in range(m)] for _ in range(n)]
для n это количество строк, а m это номер столбца, а foo это значение.
Ответ 11
t = [ [0]*10 for i in [0]*10]
для каждого элемента будет создан новый [0]*10
..
Ответ 12
используйте простейшие мысли, чтобы создать это.
wtod_list = []
и добавьте размер:
wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]
или если мы хотим сначала объявить размер. мы используем только:
wtod_list = [[0 for x in xrange(10))] for x in xrange(10)]
Ответ 13
Неверный подход: [[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
При таком подходе python не позволяет создавать другое адресное пространство для внешних столбцов и приведет к другому неправильному поведению, чем вы ожидаете.
Правильный подход, но с исключением:
y = [[0 for i in range(m)] for j in range(n)]
>>> id(y[0][0]) == id(y[1][0])
False
Это хороший подход, но есть исключение, если вы установите значение по умолчанию 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
Так что правильно установите значение по умолчанию, используя этот подход.
Абсолютно верно:
Следуйте ответу микрофона двойного цикла double loop.
Ответ 14
Matrix={}
for i in range(0,3):
for j in range(0,3):
Matrix[i,j] = raw_input("Enter the matrix:")
Ответ 15
Как указывали @Arnab и @Mike, массив не является списком. Мало различий: 1) массивы фиксированного размера во время инициализации 2) массивы обычно поддерживают меньшие операции, чем список.
Может быть, избыточный уровень в большинстве случаев, но вот базовая реализация 2d массива, которая использует реализацию аппаратного массива с использованием cythips (c библиотек) python
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])
Ответ 16
Вы можете попробовать это [[0] * 10] * 10. Это вернет 2d массив из 10 строк и 10 столбцов со значением 0 для каждой ячейки.
Ответ 17
Это лучшее, что я нашел для обучения новых программистов и без использования дополнительных библиотек. Я бы хотел что-то лучше, хотя.
def initialize_twodlist(value):
list=[]
for row in range(10):
list.append([value]*10)
return list
Ответ 18
Вот более простой способ:
import numpy as np
twoD = np.array([[]*m]*n)
Для инициализации всех ячеек с любым значением "x" используйте:
twoD = np.array([[x]*m]*n
Ответ 19
Часто я использую этот подход для инициализации 2-мерного массива
n=[[int(x) for x in input().split()] for i in range(int(input())]
Ответ 20
Общий шаблон для добавления размеров можно извлечь из этой серии:
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)
Ответ 21
Я понял одну важную вещь: при инициализации массива (в любом измерении) мы должны задать значение по умолчанию для всех позиций массива. Тогда только инициализация завершается. После этого мы можем изменить или получить новые значения для любой позиции массива. Приведенный ниже код отлично сработал для меня
N=7
F=2
#INITIALIZATION of 7 x 2 array with deafult value as 0
ar=[[0]*F for x in range(N)]
#RECEIVING NEW VALUES TO THE INITIALIZED ARRAY
for i in range(N):
for j in range(F):
ar[i][j]=int(input())
print(ar)
Ответ 22
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))