Как инициализировать двумерный массив в 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))