Я начинаю 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 = []
Это дает желаемый результат, но чувствует себя как обходной путь. Есть ли более простой / короткий / более элегантный способ сделать это?
python
multidimensional-array
thepandaatemyface
источник
источник
Ответы:
Шаблон, который часто появлялся в Python, был
что помогло мотивировать введение списочных представлений, которые преобразовывают этот фрагмент в
который короче, а иногда и понятнее. Обычно у вас появляется привычка распознавать эти и часто заменять циклы пониманием.
Ваш код следует этому шаблону дважды
источник
[foo] * 10
это список с одинаковыми точнымиfoo
10 разами, что может или не может быть важным.[foo] * 10
: Это означает , что это не будет работать , если вы заполняете массив со случайными числами (Равняется[random.randint(1,2)] * 10
до[1] * 10
или[2] * 10
это означает , что вы получите массив всех 1S или 2s, вместо случайного массива.Вы можете использовать понимание списка :
источник
i
для строк иj
столбцов, я думаю , что это должно быть лучше свопi
иj
в вашем синтаксисе для лучшего понимания и изменение диапазона 2 разных номеров.Не используйте
[[v]*n]*n
, это ловушка!но
прекрасно работает.
источник
*
копируетaddress
объект (список).[[0] * col for _ in range(row)]
.Этот способ быстрее, чем понимание вложенного списка
Вот несколько моментов времени Python3 для маленьких и больших списков
Объяснение:
[[foo]*10]*10
создает список одного и того же объекта повторяется 10 раз. Вы не можете просто использовать это, потому что изменение одного элемента изменит тот же элемент в каждой строке!x[:]
эквивалентноlist(X)
но немного более эффективно, так как избегает поиска имени. В любом случае он создает поверхностную копию каждой строки, поэтому теперь все элементы независимы.Все элементы являются одним и тем же
foo
объектом, поэтому, еслиfoo
он изменчив , вы не можете использовать эту схему., Вам придется использоватьили предполагая класс (или функцию),
Foo
которая возвращаетfoo
sисточник
copy.deepcopy
. Вам нужен план, соответствующий вашим данным, если у вас есть произвольный изменяемый объект.x
иy
. Не должно ли быть[[copy.deepcopy(foo) for y in range(10)] for x in range(10)]
[foo]*10
не создает 10 различных объектов - но легко пропустить разницу в случае, когда foo является неизменным, например,int
or илиstr
.Чтобы инициализировать двумерный массив в Python:
источник
a = [[0 for x in range(columns)] for y in range(rows)]
.источник
[[0] * col] * row
которой не получается то, что вы хотите, заключается в том, что когда вы инициализируете двухмерный список таким образом, Python не будет создавать отдельные копии каждой строки. Вместо этого он будет инициировать внешний список с указателями на ту же копию[0]*col
. Любое изменение, внесенное вами в одну из строк, будет отражено в оставшихся строках, поскольку все они фактически указывают на одни и те же данные в памяти.Обычно, когда вам нужны многомерные массивы, вам не нужен список списков, а скорее массив с пустыми данными или, возможно, dict.
Например, с NumPy вы бы сделать что-то вроде
источник
numpy
это здорово, я думаю, что это может быть немного излишним для новичка.numpy
. +1Вы можете сделать только это:
Например:
Но это имеет нежелательный побочный эффект:
источник
для n это количество строк, а m это номер столбца, а foo это значение.
источник
Если это малонаселенный массив, вам лучше использовать словарь с кортежем:
источник
для каждого элемента
[0]*10
будет создан новый ..источник
Неверный подход: [[None * m] * n]
При таком подходе python не позволяет создавать другое адресное пространство для внешних столбцов и приведет к неправильному поведению, отличному от вашего ожидания.
Правильный подход, но с исключением:
Это хороший подход, но есть исключение, если вы установите значение по умолчанию
None
Поэтому установите правильное значение по умолчанию, используя этот подход.
Абсолютно правильно:
Следуйте ответу Майка двойной петли .
источник
источник
Для инициализации 2-мерного массива используйте:
arr = [[]*m for i in range(n)]
на самом деле,
arr = [[]*m]*n
создаст 2D массив, в котором все n массивов будут указывать на один и тот же массив, поэтому любое изменение значения в любом элементе будет отражено во всех n спискахдля более подробного объяснения посетите: https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
источник
используйте простейшее мышление, чтобы создать это.
и добавьте размер:
или если мы хотим объявить размер в первую очередь. мы используем только:
источник
Как указали @Arnab и @Mike, массив не является списком. Несколько различий: 1) массивы имеют фиксированный размер во время инициализации 2) массивы обычно поддерживают меньше операций, чем список.
Может быть, в большинстве случаев это излишество, но вот базовая реализация 2d-массива, которая использует реализацию аппаратного массива с использованием Python ctypes (библиотеки c).
источник
Я понял одну важную вещь: при инициализации массива (в любом измерении) мы должны задать значение по умолчанию для всех позиций массива. Тогда только инициализация завершается. После этого мы можем изменить или получить новые значения для любой позиции массива. Код ниже работал для меня отлично
источник
Если вы используете numpy , вы можете легко создавать 2d массивы:
Икс
источник
Вышеприведенное даст вам 5x5 2D массив
Это использует понимание вложенного списка. Разбивка, как показано ниже:
[x] * col -> конечное выражение, которое вычисляется
для x in -> x будет значением, предоставленным итератором
[b для b in range (row)]] -> Iterator.
[b для b в диапазоне (строка)]] это будет оцениваться как [0,1,2,3,4], так как строка = 5,
так что теперь это упрощает
Это даст оценку [[0] * 5 для x в [0,1,2,3,4]] -> с x = 0 1-я итерация
[[1] * 5 для x в [0,1,2, 3,4]] -> с x = 1 2-й итерацией
[[2] * 5 для x в [0,1,2,3,4]] -> с x = 2 3-й итерацией
[[3] * 5 для x в [0,1,2,3,4]] -> с x = 3 4-я итерация
[[4] * 5 для x в [0,1,2,3,4]] -> с x = 4 5-я итерация
источник
Это лучшее, что я нашел для обучения новых программистов и без использования дополнительных библиотек. Я хотел бы что-нибудь получше.
источник
Вот более простой способ:
Для инициализации всех ячеек с любым значением «x» используйте:
источник
Часто я использую этот подход для инициализации 2-мерного массива
n=[[int(x) for x in input().split()] for i in range(int(input())]
источник
Общий шаблон для добавления размеров можно извлечь из этой серии:
источник
Вы можете попробовать это [[0] * 10] * 10. Это вернет 2d массив из 10 строк и 10 столбцов со значением 0 для каждой ячейки.
источник
a = [[0]*10]*10
тоa[0][0] = 1
увидите, что первый элемент в каждом ряду теперь равен 1lst = [[0] * m для i в диапазоне (n)]
инициализировать все матрицы n = строки и m = столбцы
источник
Другой способ - использовать словарь для хранения двумерного массива.
Это просто может содержать любые 1D, 2D значения и для инициализации этого
0
или любого другого значения int, использовать коллекции .источник
Код:
initial_val
должен быть неизменным.источник
источник