31. Двумерные списки (массивы, матрицы) в Python
Прежде, чем мы сделаем игру «Сапер» и «Блоки» нужно научится работать с двумерными списками.
Если просто, то двумерный список — это таблица. У каждой ячейки таблицы есть номер строки и номер столбца.
Т.е. каждая ячейка имеет не один номер, как в обычном списке, а два: номер строки и номер столбца.
Поэтому такие списки и называют «двумерными». В математике такие структуры называют «матрицы».
Создадим простой двумерный список:
a = [[1,2,3],[4,5,6]] print(a)
Не очень похоже на таблицу, правда?
А если так:
a = [[1,2,3],[4,5,6]] print(a[0]) print(a[1])
a[0] — это вся первая строка. Т.е. по сути, это элемент списка, который является списком.
len(a) — количество строк
len(a[0]) — количество элементов (столбцов) в первой строке.
Разумеется, что мы не будем заполнять и выводить это вручную.
Сначала посмотрим на вывод.
Взять все строки по очереди и вывести на экран.
for r in a: print(r)
Знакомый прием, правда? Спасибо Питону, он позволяет работать со списками просто и элегантно.
А теперь посмотрим на заполнение:
a = [] k = 10 # просто начальное значение, может быть любым for r in range(6): # 6 строк a.append([]) # создаем пустую строку for c in range(10): # в каждой строке - 10 элементов a[r].append(k) # добавляем очередной элемент в строку k += 1 # увеличиваем значение счетчика for r in a: print(r)
Начал с k = 10 для того, чтобы все числа были двузначные (попробуйте начать с k = 1 и поймете, о чем я говорю)
Теперь — заполнение случайными значениями:
a = [] for r in range(6): # 6 строк a.append([]) # создаем пустую строку for c in range(10): # в каждой строке - 10 элементов a[r].append(rnd(10,100)) # добавляем очередной элемент в строку
А теперь создадим очень простой класс и двумерный список, который заполним экземплярами этого класса:
class cell(): def __init__(self): self.n = rnd(10) a = [] nr = 6 # количество строк nc = 11 # количество столбцов for r in range(nr): a.append([]) for c in range(nc): a[r].append(cell()) # добавляем очередной элемент в строку for r in range(nr): # перебираем все строки по номерам for c in range(nc): # в каждой строке перебираем все столбцы по номерам print(a[r].n, end = ' ') # выводим на экран значения свойства "а" элемента, стоящего в данной строке и данном столбце # после вывода не нужно переходить на другую строку (на экране) - ставим пробел print() # когда выведем очередную строку, то переводим курсор (на экране) на новую строку
Усложним задачу. Сделаем класс «Ячейка» и нарисуем таблицу ячеек. Вначале класс и тестовая ячейка:
from random import randrange as rnd, choice from tkinter import * root = Tk() root.geometry('800x600') canv = Canvas(root, bg = 'white') canv.pack(fill = BOTH, expand = 1) m = 34 # размер ячеек d = 2 # размер поля вокруг ячейки nr = 6 # количество строк nc = 8 # количество столбцов x0 = m // 2 # отступ от левого края y0 = m // 2 # отступ от вернего края colors = ['red','yellow','cyan','green'] class cell(): def __init__(self, r, c): # при создании указываем номер строки и столбца, в который помещаем self.n = rnd(10) # значение, с которым будем работать self.r = r # Номер сторки в двумерном списке. self.c = c # Номер столбца . self.color = choice(colors) # случайный цвет из списка self.id = canv.create_rectangle(-100,0,-100,0,fill = self.color) # квадратик ячейки self.id_text = canv.create_text(-100,0, text = self.n, font = "Arial " + str(m//2)) # текст в квадратике, размер зависит от масштаба self.paint() def paint(self): x1 = x0 + self.c * m + d # рассчитать координаты левого верхнего угла. y1 = y0 + self.r * m + d # координаты правого нижнего угла. x2 = x1 + m - 2*d # - r y2 = y1 + m - 2*d canv.coords(self.id,x1,y1,x2,y2) canv.itemconfig(self.id,fill = self.color) # текст в центр ячейки x = (x1 + x2) / 2 y = (y1 + y2) / 2 canv.coords(self.id_text,x,y) canv.itemconfig(self.id_text, text = self.n) c_test = cell(2,2) mainloop()
В результате — грустная и одинокая «клетка» на экране. Случайного цвета и со случайным значением.
a = [] for r in range(nr): # 6 строк a.append([]) # создаем пустую строку for c in range(nc): # в каждой строке - 10 элементов a[r].append(cell(r,c)) # добавляем очередной элемент в строку mainloop()
Мы использовали класс cell, потому что это удобно — «завернуть» несколько параметров в «одну переменную». Без использования класса мы смогли бы хранить только числовое значение в ячейке. А так у нас есть уже, как минимум, два значения — это цвет и числовое значение.
Рассмотрим перебор всех ячеек. Например, приведем в соответствие цвет и значение в ячейке: выделим значения от 0 до 2 голубым, от 3 до 5 зеленым, 6 — 8 — желтым и 9 — красным:
def task(event): for r in range(nr): # перебираем все строки for c in range(nc): # перебираем все столбцы if 0 ',task) mainloop()
Не работает?
У меня тоже не работает.
Как выяснить, в чем может быть дело?
Вначале стоит проверить, выполняется ли функция task вообще. В этом поможет обычный print(‘!’)
Если выполняется, то так же нужно проверить выполнение какого-либо условия.
Все работает… но изменений-то не видно!
Ключевое слово видно.
Если еще не догадались, то подсказываю: нужно отобразить изменения.
a[r].paint()
Рассмотрим решение некоторых задач.
Найдем сумму всех:
def task(event): s = 0 for r in range(nr): for c in range(nc): s += a[r].n print(s)
А теперь выведем результат не в консоль, а прямо на холст:
def task(event): s = 0 for r in range(nr): for c in range(nc): s += a[r].n x1 = x0 + nc * m + d # координаты левого верхнего угла правой ячейки x1 = x1 + 2*m # отступим от нее на размер двух ячеек y1 = y0 x2 = x1 + m y2 = y1 + m canv.create_rectangle(x1,y1,x2,y2) x = (x2 + x1) / 2 y = (y2 + y1) / 2 canv.create_text(x,y, text = s, font = 'Arial' + str(m//2))

Заполнение значениями по порядку, по строкам:
def task(event): k = 0 for r in range(nr): for c in range(nc): a[r].n = k k += 1 a[r].color = '#99ccdd' a[r].paint()
1. Заполнить одним цветом, значениями по порядку, по строкам

2. Заполнить одним цветом, значениями по порядку, по столбцам

3. Заполнить номерами строк

4. Заполнить номерами столбцов

5. Создать таблицу сложения

6. Создать таблицу умножения
7. Заполнить повторяющимся набором (1,2,3,4,5) по строкам

8*. Заполнить повторяющимся набором (1,1,2,2,3,3,4,4,5,5). Возможно, потребуется модуль itertools
9. Заполнить двумя цветами в шахматном порядке, без чисел


Заполнить случайными цветами и числами, затем:
10. Найти сумму всех элементов
11. Найти сумму красных всего массива
12*. Найти среднее для каждого цвета, вывести рядом
13**. Нарисовать столбчатую диаграмму по суммам каждого цвета. Возможно, потребуется matplotlib
14**. Нарисовать круговую диаграмму по суммам каждого цвета
15. Выделить нули оранжевым, остальные — серым
16. Строки, в которых нет нулей сделать оранжевыми
17. Столбцы, в которых нет нулей сделать оранжевыми
Рассмотрим, как определить ячейку, по которой щелкнули мышкой.
Мы уже рассчитывали координаты по номеру строки и столбца. Надо просто сделать обратный расчет:
def task(event): c = (event.x - x0) // m r = (event.y - y0) // m a[r].color = 'orange' a[r].paint()
По щелчку:
18. Выделить оранжевым цветом элемент, по которому щелкнули, все остальные перекрасить в серый
19. Выделить оранжевым цветом все ячейки в текущем столбце
20. Выделить оранжевым цветом все ячейки в текущей строке
22. Выделить оранжевым цветом диагонали, на которых находится ячейка, все остальные отметить серым
23. Выделить оранжевым цветом соседей (слева, справа, сверху, снизу), остальные ячейки закрасить серым
24. Выделить ячейку и ее соседей по сторонам и диагоналям (все 8 ячеек)
25. Выделить ячейку, ее соседей и соседей соседей (4 + 8) Считать соседями только клетки, с которыми есть общая сторона
26. Записать 0 в ячейки, которые имеют такой же цвет, как и та, в которую щелкнули
27*. Значение ячейки, по которой щелкнули, увеличить на 50%, ее соседей на 25%, их соседей — на 10%
28. Если значение ячейки, по которой щелкнули, меньше всех своих соседей (по сторонам), то перекрасить ее в синий, если больше — то в красный. Иначе оставить, как есть.
Related Posts
- 33. Решаем проблемы с двумерным списком
- 32. Неразрешимые трудности, дублирование информации, проблема
- Форматированный вывод
Записать текст из файла в массив по словам
Записать текст в массив из файла
Подскажите пожалуйста как реализовать такое : нужно записать в массив текст из файла , который.
Как записать текст из файла в массив?
Как записать текст из файла в массив? Получается только считывать
Записать текст из файла в двумерный массив
Добрый день. Нужно загрузить текст из файла в двумерный массив. Например, текст вот такой dghgh.
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
with open('input.txt') as inp: l = inp.read().split()
Регистрация: 10.12.2015
Сообщений: 16
А можете объяснить как это работает?
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
Сообщение от Jabbson 
open(‘input.txt’)
Сообщение от Jabbson 
Сообщение от Jabbson 
Регистрация: 10.12.2015
Сообщений: 16
То есть, переменная l это куда записывается слово?
![]()
5890 / 3348 / 1034
Регистрация: 03.11.2009
Сообщений: 9,977
Это переменная, куда записывается лист «слов».
Регистрация: 10.12.2015
Сообщений: 16
Все понял, спасибо)
Регистрация: 10.12.2015
Сообщений: 16
У меня вывело такой результат,когда я попросил вывести на экран, как то можно исправить. Я так понимаю, что это дело в кодировке.
Регистрация: 10.12.2015
Сообщений: 16
и когда прошу вывести на экран один элемент этого списка, он его тоже выводит в неправильной кодировке.
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Два потока считывают текст из файла по словам
Здравствуйте, помогите пожалуйста реализовать задание: Написать программу, в которой два потока.
Чтение из текстового файла в массив с сортировкой по словам
Тема как-то коряво сформулирована, опишу тут. Допустим есть текстовый файл: Название.
Создать файл и записать в него текст. Имя файла и текст вводятся с клавиатуры
Здравствуйте. Задача примерно такая: Создать файл и записать туда текст. Когда создаем файл пишем.
Из файла прочитать текст и в этом тексте заменить все пробелы на _ и записать исправленный текст обратно
задача написать программу на assembler, под dos Нужно из файла прочитать текст и в этом тексте.

Прочитать текст из файла, затем удалить из текста все буквы вашего имени и записать текст в новый файл
Создать Windows – приложение, в котором производите запись считывание текста из файла, затем.
Криптор exe программ: в начало файла записать пароль. Файл записать как массив байтов
Привет всем. Начал писать криптор и сразу запутался. Как известно, то криптор копирует исходный.
Python создание и заполнение двумерного массива
Я недавно в питоне и непонятно вот что, при создании массива таким способом:
b = [[0] * 2] * 2
И заполнении:
for i in range(w): for r in range(l): print(i,r) b[i][r] = str(i) + str(r)
Массив заполняется не 00; 01; 10; 11, а 10; 11; 10; 11.
- Вопрос задан более трёх лет назад
- 125608 просмотров
Комментировать
Решения вопроса 3
Пример без numpy, вообще без внешних библиотек
#!/usr/bin/env python3 a = 3 b = 5 r = 0 # Чтобы было, чем заполнять mas = [] for i in range(a): mas.append([]) for j in range(b): mas[i].append(r) r += 1 # Чтобы заполнялось не одно и тоже print(mas) # [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]
Ответ написан более трёх лет назад
Нравится 7 1 комментарий
Rapt @Rapt Автор вопроса
Вот, пойдет!
ты создаешь список, а потом умножаешь его на 2, таким образом он не клонируется, а копируется сам объект со всеми его адресами, поэтому b[0][0] == b[1][0] и b[0][1] == b[1][1], так как у тебя в b[0] находится тот же объект что и в b[1].
Если хочешь создавать многомерные массивы используй:
b = numpy.array(range(4))
b.shape = (2,2)
Ответ написан более трёх лет назад
Нравится 3 3 комментария
Rapt @Rapt Автор вопроса
Как подключить numpy на linux?)
import numoy
если нет — скачать либы с офф сайта www.scipy.org/scipylib/download.html
еще она может numeric называться
import numpy*

Andrey Dugin @adugin Куратор тега Python
>>> dx = 2 >>> dy = 3 >>> matrix = [[0 for x in xrange(dx)] for y in xrange(dy)] >>> matrix [[0, 0], [0, 0], [0, 0]] >>> matrix[0][0] = 1 >>> matrix [[1, 0], [0, 0], [0, 0]]
Определение двумерного массива в Python
Часто в программировании приходится работать с двумерными массивами. Определение двумерного массива в Python может вызвать затруднения у новичков, так как Python не предоставляет встроенного типа для двумерных массивов, как это происходит в некоторых других языках программирования.
Рассмотрим типичную проблему: необходимо определить двумерный массив без заданной заранее длины.
matrix = [][]
Такой код приведет к ошибке IndexError: list index out of range , потому что Python пытается получить доступ к несуществующему элементу списка.
Решение
В Python двумерный массив можно определить с помощью списка списков. Каждый подсписок будет представлять собой отдельную строку в двумерном массиве. Например, можно определить двумерный массив следующим образом:
matrix = [[], []]
Теперь matrix представляет собой двумерный массив, состоящий из двух пустых строк. Можно добавить элементы в эти строки с помощью метода append :
matrix[0].append(1) matrix[1].append(2)
Сейчас matrix выглядит так:
Это двумерный массив с двумя строками и одним столбцом. Можно продолжать добавлять элементы в строки по мере необходимости.
Таким образом, для определения двумерного массива в Python необходимо использовать список списков.
