Программирование аркадных игр
и обучение информатикеChapter 7: Знакомство со списками
7.1 Типы данных
До этого момента, в книге были описаны четыре типа данных:
- String (строка, сокращённо от “string of characters,” воспринимающееся нормальными людьми как текст.)
- Integer (целое число)
- Floating point (число с плавающей точкой, дробное число)
- Boolean (истинное или ложное)
Python может отображать тип данных определённого значения с помощью функции type. Признаться, это не слишком полезно для программ, которые мы пишем, однако эта функция пригодиться нам в этот раз для демонстрации типов данных, которые были представлены нам до этой главы. Введите следующее в интерактивную консоль IDLE: (Не создавайте новое окно и не пишите это как программу: это не сработает.)
type(3) type(3.145) type("Hi there") type(True) |
Вывод:
>>> type(3) <class 'int'> >>> type(3.145) <class 'float'> >>> type("Hi there") <class 'str'> >>> type(True) <class 'bool'> |
Также, возможно использовать функцию type на переменной, чтобы посмотреть содержащиеся в ней данные.
x=3 type(x)
Два новых представленных типа данных в этой главе будут Lists(списки) и Tuples(кортежи). Попробуйте запустить следующие команды в интерактивной консоли Python'а и посмотрите, что отображается:
type( (2,3,4,5) ) type( [2,3,4,5] )
7.2 Работа со списками
Попробуйте ввести эти примеры в консоли IDLE. Чтобы создать список и напечатать его, сделайте следующее:
>>> x=[1,2] >>> print (x) [1, 2]
Чтобы вывести отдельный элемент из списка:
>>> print (x[0]) 1
Заметьте, что адресация элементов списка начинается с нуля. Так что список с 10 элементами не будет содержать ничего по адресу [10]. Только ячейки от [0] до [9]. Легко запутаться, создавая массив из 10 элементов, но не имея доступа к элементу по адресу 10.
Программа может присваивать новые значения индивидуальным элементам списка. В случае ниже, первому месту по нулевому адресу (не первому) присваивается число 22.
>>> x[0]=22 >>> print (x) [22, 2]
Также, программа может создать “кортеж.” Этот тип данных работает так же, как и список, но с двумя исключениями. Во первых, он создаётся в круглых, а не в квадратных скобках. Во вторых - невозможно изменить кортеж после его создания. Посмотрите ниже:
>>> x=(1,2) >>> print (x) (1, 2) >>> print (x[0]) 1 >>> x[0]=22 Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> x[0]=22 TypeError: 'tuple' object does not support item assignment >>>
Как можно наблюдать в вышеприведённом коде, присвоение, которое могло быть выполнено со списком, не работает в случае с кортежем.
Массив - это список объектов. Эта структура данных очень важна в информатике. Тип данных “list” в Python по своей сути очень похож на массив.
7.3 Обход списка
Если программе нужно проходить через каждый элемент в списке, например, с целью их выведения на экран, есть два типа циклов, которые помогут достигнуть решения этой задачи.
Первый - идти через каждый элемент в цикле, используя “for-each”. Этот тип цикла берёт список вещей и идёт по нему, элемент за элементом. Он возьмёт копию выбранного элемента и сохранит её в отдельной переменной для обработки.
Формат команды:
for переменная_элемента in имя_списка:
Вот несколько примеров:
my_list=[101,20,10,50,60] for item in my_list: print( item ) |
Вывод:
101 20 10 50 60 |
Программы могут хранить строки внутри списков:
my_list=["Spoon", "Fork", "Knife"] for item in my_list: print( item ) |
Вывод:
Spoon Knife Fork |
Списки даже могут содержать другие списки. Этот цикл проходит через каждый элемент в основном списке, но не трогает элементы дочерних списков.
my_list=[ [2,3], [4,3], [6,7] ] for item in my_list: print( item ) |
Вывод:
[2,3] [4,3] [6,7] |
Другой способ - прохождение через список, используя переменную индекса, получая прямой доступ к списку. Чтобы использовать переменную индекса, программа считает от нуля до длины списка (не включительно). Если в списке десять элементов, цикл должен пройти от 0 до 9, в целом обходя 10 элементов.
Длина списка может быть найдена с помощью функции len. Комбинируя её с функцией range, мы можем пройти через индексы всего списка.
my_list=[101,20,10,50,60] for i in range( len(my_list) ): print( my_list[i] ) |
Вывод:
101 20 10 50 60 |
Этот метод более сложный, но, в то же время, более сильный. Потому что мы работаем напрямую с элементами списка, а не их копиями, список может быть изменён. Цикл for-each не позволяет менять исходный список.
7.4 Добавление в список
Новые элементы могут быть добавлены в список (но не в кортеж) используя команду append. Например:
my_list=[2,4,5,6] print(my_list) my_list.append(9) print(my_list) |
Вывод:
[2,4,5,6] [2,4,5,6,9] |
Заметка: Если производительность во время добавление в список важна, важно понять, как реализован список. Например, если список реализован как массив, то добавление в список - не то же самое, что и добавление яйца в старую, полную коробку с яйцами. Новая коробка, в которой тринадцать ячеек для яиц, должна быть сделана. Затем, двенадцать яиц из предыдущей коробки должны быть перемещены в новую. И только потом уже можно добавить тринадцатое яйцо. Затем, старая коробка от яиц выбрасывается. Потому что такое может происходить без ведома программиста, позади реализации стандартной функции, он может забыть это и предоставить компьютеру выполнение всей этой работы. Было бы более эффективным с самого начала сказать компьютеру сделать большую коробку для яиц. К счастью, Python не хранит список как массив. Но это важно запомнить, потому что такой подход часто используется в других языках программирования.
Для создания списка с нуля, необходим пустой список и функция append. Вот пример создания списка, основываясь на вводе пользователя:
my_list=[] # Empty list for i in range(5): userInput = input( "Введите число: ") userInput = int( userInput ) my_list.append(userInput) print(my_list) |
Вывод:
Введите число: 4 [4] Введите число: 5 [4, 5] Введите число: 3 [4, 5, 3] Введите число: 1 [4, 5, 3, 1] Введите число: 8 [4, 5, 3, 1, 8] |
Если программе нужно создать массив определённой длины, заполненный одинаковыми значениями, существует простой способ, показанный в коде ниже:
# Создать массив со 100 нулями. my_list = [0] * 100
7.5 Суммирование или изменение списка
Создание суммы элементов массива - частое действие. Вот как это делается:
# Копия суммируемого массива myArray = [5,76,8,5,3,3,56,5,23] # Начальная сумма должна равняться нулю arrayTotal = 0 # Цикл от 0 до количества элементов # в массива: for i in range( len(myArray) ): # Добавить элемент 0, затем элемент 1, затем 2, и т.д. arrayTotal += myArray[i] # Вывести результат print( arrayTotal )
Вместо того, чтобы использовать range, то же самое можно сделать идя напрямую через массив, используя for.
# Копия суммируемого массива myArray = [5,76,8,5,3,3,56,5,23] # Начальная сумма должна равняться нулю arrayTotal = 0 # Пройти через массив, копируя каждый элемент массива в # переменную с именем item. for item in myArray: # Добавить item к сумме arrayTotal += item # Вывести результат print( arrayTotal )
Числа в массива также могут быть изменены при помощиNumbers in an array can also be changed by using цикла for:
# Копия изменяемого массива myArray = [5,76,8,5,3,3,56,5,23] # Цикл от 0 до числа элементов # в массиве: for i in range( len(myArray) ): # Изменить элемент удвоив его myArray[i] = myArray[i] * 2 # Вывести результат print( myArray )
Однако, вторая версия не работает с удваиванием значений в массиве Почему? Потому что item - копия выбранного элемента массива Нижеприведённый код удваивает копию, но не оригинальный элемент массива.
# Копия изменяемого массива myArray = [5,76,8,5,3,3,56,5,23] # Пройти через каждый элемент в myArray for item in myArray: # Это удваивает переменную item, но не меняет массив # потому что item - копия одного элемента. item = item * 2 # Вывести результат print( myArray )
7.6 Разделение строк
Строки также являются списками. Запустите следующий код с двумя версиями x:
x="This is a sample string" #x="0123456789" print ("x=",x) # Доступ к одному символу print ("x[0]=",x[0]) print ("x[1]=",x[1]) # Доступ с правой стороны print ("x[-1]=",x[-1]) # Доступ 0-5 print ("x[:6]=",x[:6]) # Доступ 6 print ("x[6:]=",x[6:]) # Доступ 6-8 print ("x[6:9]=",x[6:9])
Строки в Python могут быть использованы с математическими операторами. Попробуй запустить следующий код и поймите, что он делает:
a="Hi" b="There" c="!" print (a+b) print (a+b+c) print (3*a) print (a*3) print ((a*2)+(b*2))
Возможно узнать длину строки. Также, возможно сделать это с любым типом массива.
a="Hi There" print (len(a)) b=[3,4,5,6,76,4,3,3] print (len(b))
В связи с тем, что строка - это массив, программа может идти через каждый символ так же, как и в любом списке:
for character in "This is a test.": print (character)
Упражнение: взяв за основу следующий код:
months="JanFebMarAprMayJunJulAugSepOctNovDec" n=int(input("Enter a month number: "))
Вывести на экран аббревиатуру месяца, основываясь на числе, которое вводит пользователь. (Вычислите начальную позицию строки, затем используйте новый материал для вывода правильной части строки.)
7.7 Секретные коды
Этот код выводит каждую букву строки отдельно:
plain_text="This is a test. ABC abc" for c in plain_text: print (c, end=" ")
Компьютер не хранит буквы строки в памяти, он хранит последовательность чисел. Каждое число обозначает букву. Таблица, которую компьютеры используют для перевода чисел в буквы, называется American Standard Code for Information Interchange (ASCII). Существует много других таблиц, эти таблицы могут поддерживать кириллицу, кандзи, а также другие международные символы. По умолчанию, Python использует ASCII.
Таблица ASCII содержит в себе числа 0-255. Каждой букве соответствует один байт в памяти. Часть таблицы ASCII показана ниже:
Значение | Символ | Значение | Символ | Значение | Символ | Значение | Символ |
40 | ( | 61 | = | 82 | R | 103 | g |
41 | ) | 62 | > | 83 | S | 104 | h |
42 | * | 63 | ? | 84 | T | 105 | i |
43 | + | 64 | @ | 85 | U | 106 | j |
44 | , | 65 | A | 86 | V | 107 | k |
45 | - | 66 | B | 87 | W | 108 | l |
46 | . | 67 | C | 88 | X | 109 | m |
47 | / | 68 | D | 89 | Y | 110 | n |
48 | 0 | 69 | E | 90 | Z | 111 | o |
49 | 1 | 70 | F | 91 | [ | 112 | p |
50 | 2 | 71 | G | 92 | \ | 113 | q |
51 | 3 | 72 | H | 93 | ] | 114 | r |
52 | 4 | 73 | I | 94 | ^ | 115 | s |
53 | 5 | 74 | J | 95 | _ | 116 | t |
54 | 6 | 75 | K | 96 | ` | 117 | u |
55 | 7 | 76 | L | 97 | a | 118 | v |
56 | 8 | 77 | M | 98 | b | 119 | w |
57 | 9 | 78 | N | 99 | c | 120 | x |
58 | : | 79 | O | 100 | d | 121 | y |
59 | ; | 80 | P | 101 | e | 122 | z |
60 | < | 81 | Q | 102 | f |
Для дополнительной информации по ASCII, ознакомьтесь с:
http://en.wikipedia.org/wiki/ASCII
Следующий код конвертирует каждую из букв в предыдущем примере в их числовое значение, используя таблицу ASCII.
plain_text="This is a test. ABC abc" for c in plain_text: print (ord(c), end=" ")
Следующая программа берёт каждое значение ASCII и прибавляет к нему единицу. Потом оно выводит новое значение ASCII, затем конвертирует значение обратно в букву.
plain_text="This is a test. ABC abc" for c in plain_text: x=ord(c) x=x+1 c2=chr(x) print (c2, end="")
Следующий код, берёт каждое значение ASCII и прибавляет к нему единицу. Затем, он выводит букву, соответствующую новому значению.
# Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Explanation video: http://youtu.be/sxFIxD8Gd3A plain_text = "This is a test. ABC abc" encrypted_text = "" for c in plain_text: x = ord(c) x = x + 1 c2 = chr(x) encrypted_text = encrypted_text + c2 print(encrypted_text)
И, наконец, последний образец кода берёт каждое значение ASCII и отнимает от него единицу. Затем, он конвертирует значение обратно в букву. Передавая программе вывод из предыдущей программы, мы превращаем её в дешифровщик текста, зашифрованного в прошлом примере.
# Sample Python/Pygame Programs # Simpson College Computer Science # http://programarcadegames.com/ # http://simpson.edu/computer-science/ # Explanation video: http://youtu.be/sxFIxD8Gd3A encrypted_text = "Uijt!jt!b!uftu/!BCD!bcd" plain_text = "" for c in encrypted_text: x = ord(c) x = x - 1 c2 = chr(x) plain_text = plain_text + c2 print(plain_text)
7.8 Ассоциативные массивы
Python не ограничивается использованием чисел как индексов в массивах. Так же возможно использовать ассоциативный массив. Он работает следующим образом:
# Создать пустой ассоциативный массив # (Обратите внимание на фигурные скобки) x={} # Добавить в него новых элементов x["fred"]=2 x["scooby"]=8 x["wilma"]=1 # Достать и вывести элемент на экран print (x["fred"])
В этой книге ассоциативные массивы не применяются, однако я считаю, что важно указать на возможность их использования.
7.9 Повторение пройденного
Пройдите тест с несколькими вариантами ответов (на англ. яз.).
После прохождения теста и ответов на нижеприведённые вопросы, попробуйте выполнить Цикличную лабораторную работу. Затем, попробуйте пройти Тест 1 из списка тестов.
- Перечислите четыре типа данных, которые мы прошли, а также приведите пример каждого:
- Что выводит этот код?
my_list=[5,2,6,8,101] print(my_list[1]) print(my_list[4]) print(my_list[5])
- Что выводит этот код?
my_list=[5,2,6,8,101] for my_item in my_list: print (my_item)
- Что выводит этот код?
my_list1=[5,2,6,8,101] my_list2=(5,2,6,8,101) my_list1[3]=10 print(my_list1) my_list2[2]=10 print(my_list2)
- Что выводит этот код?
word = "Simpson" for letter in word: print (letter)
- Что выводит этот код?
my_text="The quick brown fox jumped over the lazy dogs." print ("The 3rd spot is: "+my_text[3]) print ("The -1 spot is: "+my_text[-1])
- Что выводит эта программа?
s="0123456789" print (s[1]) print (s[:3]) print (s[3:])
- Напишите код, который возьмёт строку, введённую пользователем, а затем выведет её длину. Затем, выведите первую букву строки.
- Напишите цикл, который возьмёт пять номеров у пользователя и добавит их в массив. Затем, выведите этот массив.
- Напишите программу, которая берёт следующий массив и выводит среднее арифметическое его элементов:
my_list=[3,12,3,5,3,4,6,8,5,3,5,6,3,2,4]
You are not logged in. Log in here and track your progress.
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin