содержание
содержание Введение в списки Python функция “id” Просто списки Список против … Дальнейшее чтение Вывод
Введение в списки Python
По-видимому, существует довольно много путаницы вокруг списков Python и некоторых структур данных, сопоставимых со списками. Что такое список? Как он сравнивается с кортежем и набором? Как насчет словарей? Что такое изменчивость? Что такое итераторы и стоит ли о них заботиться?
Эта статья направлена на то, чтобы устранить некоторую путаницу вокруг этих вопросов и многого другого. Мы начнем с рассмотрения списков в отдельности: как мы их составляем и как с ними взаимодействовать. После этого мы рассмотрим некоторые примеры использования циклов, понимания и рекурсии для создания списков. Мы закончим, сравнив списки с некоторыми другими итеративными типами.
Версия
Все приведенные ниже примеры написаны на Python3. Если вы используете этот материал в Python2, некоторые вещи могут получиться немного по-другому.
функция id
В следующих примерах мы будем довольно часто использовать встроенную в Python функцию id
, поэтому начнем с того, что убедимся, что мы ее поняли.
>>> id>>> print(id.__doc__) Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects. (CPython uses the object's memory address.) >>> >>> # let's see it in action >>> >>> a = 1 >>> id(a) 10919424 >>> >>> >>> b = a >>> >>> id(b) == id(a) True >>> >>> id(b) == id('spam') False
Таким образом, на простом английском языке функция id
возвращает что-то, что представляет уникальную идентичность объекта. Если у нас есть два значения, которые имеют один и тот же выходной идентификатор, то они являются одним и тем же объектом. То есть они находятся в одном и том же месте в памяти.
В качестве аналогии предположим, что у нас есть человек по имени Роберт. Мать зовет его Робертом, братья и сестры-Робом, а друзья-Бобом. Номер социального страхования Боба совпадает с номером социального страхования Роберта. Номер социального страхования Роба такой же, как у Боба.
В Python это похоже на:
>>> id(bob) == id(robert) True >>> id(rob) == id(bob) True
Это также означает, что если вы сделаете что-то, что изменит Роба, это повлияет на Роберта и Боба. Если Роб решит надеть голубую футболку, то это означает, что Роберт и Боб носят голубую футболку-это одна и та же футболка. Так:
>>> id(bob.shirt) == id(robert.shirt) True >>> id(rob.shirt) == id(bob.shirt) True
Просто списки
В этом разделе мы рассмотрим несколько примеров. Начнем с простого. Откройте оболочку Python3, если вы хотите следовать за ней.
Создание списков
Во-первых, некоторый базовый синтаксис для создания списков.
Давайте составим наш первый список:
>>> l1 = [1,2,3] >>> l1 [1, 2, 3] >>> >>> >>> type(l1)>>>
Таким образом, l1
является экземпляром класса с именем list
. Списки-это объекты. l1
был списком целых чисел. Давайте составим список строк.
>>> l2 = ['a','b','c'] >>> l2 ['a', 'b', 'c']
Мы также можем ссылаться на другие переменные из списков.
>>> foo = 'b' >>> l2 = ['a',foo,'c'] >>> l2 ['a', 'b', 'c']
Конечные запятые и пробелы вокруг отдельных элементов не имеют значения в том, как интерпретируются вещи. Это означает, что следующие утверждения эквивалентны:
>>> l2 = ['a',foo,'c'] >>> l2 = ['a',foo,'c' , ]
Списки также могут быть разбросаны по нескольким строкам. Иногда приятно сделать это для удобства чтения.
>>> l1 = [ ... 1, # this can also be useful if you want to ... 2, # make comments about specific elements in ... 3 # your list ... ] >>> l1 [1, 2, 3]
Один список может содержать данные многих типов. Например, этот содержит целые числа, а также строки:
>>> l3 = [1, 2, 3, 'a', 'b', 'c'] >>> l3 [1, 2, 3, 'a', 'b', 'c']
Списки могут даже содержать списки!
>>> l4 = [1,2,[3,4,[5]],'a',3.2,True] >>> l4 [1, 2, [3, 4, [5]], 'a', 3.2, True]
Пока все хорошо. Теперь вы можете распознавать и создавать списки.
Доступ к отдельным элементам
Теперь мы будем использовать индексы для доступа к отдельным элементам в наших списках:
>>> l4 [1, 2, [3, 4, [5]], 'a', 3.2, True]
Индексы начинаются с 0. Таким образом, первый элемент имеет индекс 0, второй элемент имеет индекс 1 и т. Д.
>>> l4[0] 1 >>> l4[1] 2 >>> l4[2] [3, 4, [5]] >>> l4[3] 'a' >>> l4[4] 3.2 >>> l4[5] True
Это был наш последний элемент. Если мы попытаемся получить доступ к элементу после конца списка, Python вызовет ошибку IndexError:
>>> l4[6] Traceback (most recent call last): File "", line 1, in IndexError: list index out of range
И если вы передадите индекс, который Python не понимает, вы получите ошибку типа:
>>> l4['eggs'] Traceback (most recent call last): File "", line 1, in TypeError: list indices must be integers or slices, not str >>> >>> l4[1.0] Traceback (most recent call last): File " ", line 1, in TypeError: list indices must be integers or slices, not float >>> >>> l4[1] 2
Таким образом, в соответствии с этими ошибками типа, индексы списка должны быть целыми числами или срезами. Мы рассмотрели положительные целые числа. Теперь о некоторых негативных:
>>> l4 [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[-1] True >>> l4[-2] 3.2 >>> l4[-3] 'a' >>> l4[-4] [3, 4, [5]] >>> l4[-5] 2 >>> l4[-6] 1 >>> l4[-7] Traceback (most recent call last): File "", line 1, in IndexError: list index out of range
Таким образом, наш список состоит из шести элементов, самый высокий целочисленный индекс равен 5, а самый низкий целочисленный индекс -6. Это выглядит немного похоже на:
Нарезка и нарезка кубиками
Индексы списка должны быть целыми числами или срезами, и в этом разделе мы рассмотрим последние. Нарезка-это механизм создания новых списков из существующих списков, в котором новый список является просто подмножеством исходного списка. Чтобы понять срезы, вам нужно понять целочисленные индексы.
– Готовы?
Slice-это класс, определенный в Python по умолчанию. Вам не нужно ничего импортировать, чтобы использовать его.
>>> slice>>> print(slice.__doc__) slice(stop) slice(start, stop[, step]) Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).
Ладно, это немного сбивает с толку. Давайте посмотрим, что произойдет, если мы используем срез в качестве индекса.
>>> l4 [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l5 = l4[slice(0,6,1)] >>> l5 [1, 2, [3, 4, [5]], 'a', 3.2, True]
Итак, l4
и l5
– это одно и то же… или они? Помните ту функцию id
, о которой я бубнил раньше? Вот где это вступает в игру:
>>> id(l4)==id(l5) False
Итак, l5
выглядит как l4
, но на самом деле это просто копия. Возвращаясь к аналогии, которую мы использовали ранее: если l4
был Робом, то l5
похож на близнеца Роба. Давай позвоним ей… Роберта. Но подождите, это еще не все:
>>> id(l4[0])==id(l5[0]) True >>> id(l4[1])==id(l5[1]) True >>> id(l4[2])==id(l5[2]) True
Таким образом, l4
и l5
различны, но их содержимое находится в одном и том же месте в памяти.
Продолжим нашу аналогию: допустим, у Роберта и Роберты есть полка с книгами, которые они делят. Если Роберта снимает с полки одну из своих книг, значит, она сняла с полки одну из книг Роберта (потому что это одна и та же книга). Если Роберт уронил одну из своих книг в ванну, значит, он уронил в ванну одну из книг Роберты (потому что это одна и та же книга) (Черт возьми, Роберт!).
Точно так же, как Роберта и Роберт делятся одними и теми же книгами, l4
и l5
делятся одним и тем же содержанием. Технический способ сказать это таков: l5
является неглубокой копией l4
. Это может быть немного неожиданным, но:
>>> id(l4[slice(0,6,1)]) == id(l4[slice(0,6,1)]) True
Тот же начальный список, нарезанный одним и тем же срезом, возвращает ту же копию!
Позже мы подробнее остановимся на значении памяти. Сейчас это может показаться довольно простым, но я видел несколько довольно странных ошибок в этом поведении. Давайте подробнее рассмотрим, какие кусочки мы можем сделать:
Ранее мы делали это:
>>> l5 = l4[slice(0,6,1)] >>> l5 [1, 2, [3, 4, [5]], 'a', 3.2, True]
У Python есть хорошая стенография, которую мы будем использовать сейчас. Это эквивалентно тому, что мы делали раньше.
>>> l5 = l4[0:6:1] >>> l5 [1, 2, [3, 4, [5]], 'a', 3.2, True]
Аргументы slice называются start
, stop
и step
. Мы изменим каждый из них, чтобы посмотреть, что он делает в первую очередь. Давайте посмотрим на start
:
>>> l4[0:6:1] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[1:6:1] [2, [3, 4, [5]], 'a', 3.2, True] >>> l4[2:6:1] [[3, 4, [5]], 'a', 3.2, True] >>> l4[-1:6:1] [True] >>> l4[-2:6:1] [3.2, True]
В общем: some_list[start:stop:step][0][start]
. Но если вы ссылаетесь на какой-то индекс в конце списка, то slice не вызывает исключения.
>>> l4[5000:6:1] [] >>> l4[-5000:6:1] [1, 2, [3, 4, [5]], 'a', 3.2, True]
Теперь давайте посмотрим на stop
. Имейте в виду, что последний элемент l4
является истинным и имеет индекс 5.
>>> l4[0:6:1] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:5:1] [1, 2, [3, 4, [5]], 'a', 3.2] >>> l4[0:4:1] [1, 2, [3, 4, [5]], 'a'] >>> l4[0:-1:1] [1, 2, [3, 4, [5]], 'a', 3.2] >>> l4[0:-2:1] [1, 2, [3, 4, [5]], 'a'] >>> l4[0:-3:1] [1, 2, [3, 4, [5]]]
В общем: some_list[start,stop:step][-1][step-1]
. И опять же, можно ссылаться на индексы в конце списка:
>>> l4[0:5000:1] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:-5000:1] []
Последний аргумент – шаг
:
>>> l4[0:6:1] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:6:2] [1, [3, 4, [5]], 3.2] >>> l4[0:6:3] [1, 'a'] >>> l4[0:6:4] [1, 3.2] >>> l4[0:6:-1] >>> [] >>> l4[6:0:-1] [True, 3.2, 'a', [3, 4, [5]], 2] >>> l4[6:0:-2] [True, 'a', 2]
Поэтому, если шаг
равен 1, то мы возвращаем каждый элемент в списке. Если шаг 2
, мы возвращаем каждый второй элемент. Отрицательные значения step
меняют порядок списка, что означает, что start
и stop
нуждаются в соответствующих значениях. Если шаг
положительный, то имеет смысл, что start < stop
. Но если шаг
отрицательный, то stop < start
будет иметь больше смысла.
Молодец! теперь вы можете нарезать как профессионал. Есть еще одна вещь, которую стоит знать: не все параметры среза обязательны.
Ниже приведены еще несколько ярлыков, которые вы можете использовать.
Во-первых, шаг по умолчанию равен 1, поэтому, если вы оставите это, все будет хорошо. Все следующие эквивалентны:
>>> l4[0:6:1] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:6:] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:6] [1, 2, [3, 4, [5]], 'a', 3.2, True]
Пока есть двоеточие :
, индекс считается срезом. Параметры start и stop slice также являются необязательными. Следующие эквивалентны:
>>> l4[0:6] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[:6] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[0:] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[:] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[::] [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[::1] [1, 2, [3, 4, [5]], 'a', 3.2, True]
Это также работает, если вы укажете отрицательный шаг.
>>> l4[5:-7:-1] [True, 3.2, 'a', [3, 4, [5]], 2, 1] >>> l4[:-7:-1] [True, 3.2, 'a', [3, 4, [5]], 2, 1] >>> l4[5::-1] [True, 3.2, 'a', [3, 4, [5]], 2, 1] >>> l4[::-1] [True, 3.2, 'a', [3, 4, [5]], 2, 1]
Потрясающая работа! Это все, что вам нужно знать о нарезке.
Операции и функции общего списка
В списках есть нечто большее, чем нарезка и нарезка кубиками. Здесь мы рассмотрим некоторые общие функции.
добавить
добавляет элемент в конец списка.
>>> l=[] >>> l [] >>> l.append('a') >>> l ['a'] >>> l.append([1,2]) >>> l ['a', [1, 2]] >>> l.append(1,2) Traceback (most recent call last): File "", line 1, in TypeError: append() takes exactly one argument (2 given)
extend
используется для объединения списков. Обратите внимание на то, как это отличается от добавления:
>>> l ['a', [1, 2]] >>> l.extend() Traceback (most recent call last): File "", line 1, in TypeError: extend() takes exactly one argument (0 given) >>> l.extend([]) >>> l ['a', [1, 2]] >>> l.extend([1,2,3,4,5]) >>> l ['a', [1, 2], 1, 2, 3, 4, 5]
in
используется для проверки наличия элемента в списке:
>>> l ['a', [1, 2], 1, 2, 3, 4, 5] >>> 'a' in l True >>> 'b' in l False
не в
делает обратное:
>>> 'b' not in l True >>> 'a' not in l False
сортировка
сортирует список на месте и сортирует
возвращает новый список, который упорядочен правильно:
>>> l = [111,4,22,6,30] >>> >>> sorted(l) [4, 6, 22, 30, 111] >>> l [111, 4, 22, 6, 30] >>> l.sort() >>> l [4, 6, 22, 30, 111]
И, наконец, вы можете изменить отдельные элементы в списке с помощью назначения:
>>> l = [1,2,3] >>> l [1, 2, 3] >>> l[0] = 'new' >>> l ['new', 2, 3] >>> l[3] = 'new' Traceback (most recent call last): File "", line 1, in IndexError: list assignment index out of range
Изменчивость и память имеют значение
В этом разделе мы рассмотрим несколько проблемных моментов. Такое поведение может привести к некоторым очень запутанным ошибкам.
Как мы уже видели, списки изменчивы. Это означает, что вы можете изменять части списка без создания целого нового списка:
>>> l1 = [1,2,3] >>> l1 [1, 2, 3] >>> id(l1) 139786247365704 >>> original_id = id(l1) >>> l1[1] = "updated" >>> l1 [1, 'updated', 3] >>> id(l1) == original_id True
Поэтому, если у нас есть две переменные, указывающие на один и тот же список, то изменение одного списка изменит их обоих:
>>> l1 [1, 'updated', 3] >>> l2 = l1 >>> l2 [1, 'updated', 3] >>> id(l1) == id(l2) True >>> l2.append('parrot') >>> l2 [1, 'updated', 3, 'parrot'] >>> l1 [1, 'updated', 3, 'parrot']
Такое поведение применимо даже к вложенным структурам данных:
>>> # l4 contains a list. We're going to point at it from another variable >>> l4 [1, 2, [3, 4, [5]], 'a', 3.2, True] >>> l4[2] [3, 4, [5]] >>> l5 = l4[2] >>> l5 [3, 4, [5]] >>> l4[2][0] 3 >>> l5[0] 3 >>> l4[2][1] 4 >>> l5[1] 4 >>> l4[2][2] [5] >>> l5[2] [5] >>> >>> id(l5) == id(l4[2]) True
Итак, l4[2]
и l5
относятся к одной и той же области в памяти (например, Роб и Роберт-один и тот же человек).
>>> l5.extend(['cheddar','gouda']) >>> l5 [3, 4, [5], 'cheddar', 'gouda'] >>> l4[2] [3, 4, [5], 'cheddar', 'gouda'] >>> l4 [1, 2, [3, 4, [5], 'cheddar', 'gouda'], 'a', 3.2, True]
Пока все хорошо… теперь о некоторых потенциально запутанных битах:
>>> id(l4[2]) == id(l5) True >>> l5 [3, 4, [5], 'cheddar', 'gouda'] >>> l5 = ['ni'] >>> l5 ['ni'] >>> l4[2] [3, 4, [5], 'cheddar', 'gouda'] >>> id(l4[2]) == id(l5) False
Вот что произошло: мы создали новый список и назначили его l5
. l5
теперь указывает на совершенно новую ячейку памяти.
Эта версия изменяет список без создания нового:
>>> l5 = l4[2] >>> id(l4[2]) == id(l5) True >>> l5 [3, 4, [5], 'cheddar', 'gouda'] >>> l5.clear() >>> l5.append('ni') >>> l5 ['ni'] >>> l4[2] ['ni'] >>> id(l4[2]) == id(l5) True
Списки в качестве аргументов функции
Я видел, как путаница вокруг этого материала вызывает много ошибок.
>>> def spam(some_list): ... some_list.append(1) ... return some_list ... >>> l = [] >>> spam(l) [1] >>> spam(l) [1, 1] >>> spam(l) [1, 1, 1] >>> l [1, 1, 1]
Таким образом, список, который передается в нашу функцию spam
, мутирует при каждом вызове функции. Довольно очевидно, не так ли?
Именно так ведут себя аргументы списка по умолчанию:
>>> def eggs(some_list=[]): ... some_list.append(1) ... return some_list ... >>> eggs() [1] >>> eggs() [1, 1] >>> eggs() [1, 1, 1] >>> id(eggs()) 139786247382088 >>> id(eggs()) 139786247382088
Яйца продолжают возвращать один и тот же объект списка. Список был создан, когда функция была определена в первый раз. Теперь давайте создадим новый список и передадим его:
>>> >>> l=['something_new'] >>> eggs(l) ['something_new', 1] >>> eggs(l) ['something_new', 1, 1] >>> eggs(l) ['something_new', 1, 1, 1] >>> >>> # So now it behaves like our spam function >>> >>> # how about this: >>> >>> eggs([]) [1] >>> eggs([]) [1] >>> eggs([]) [1]
Мораль этой истории: яйца
должны быть сожжены как ведьма. Изменяемые параметры по умолчанию опасны! Избегайте их. Ниже приведен более безопасный способ делать вещи. Теперь поведение по умолчанию не меняется при каждом вызове функции.
>>> def better_eggs(some_list=None): ... if some_list == None: ... some_list = [] ... some_list.append(1) ... return some_list ... >>> better_eggs() [1] >>> better_eggs() [1] >>> better_eggs() [1]
Резюмировать
В этом разделе нам удалось разобраться во всех вещах. Мы можем создавать и мутировать их, мы можем извлекать разные их части по-разному, и мы можем избежать некоторых странных ошибок с успехом.
Список против …
Списки – это здорово и все такое, но они не единственные встроенные итерационные функции, которые может предложить Python. В этом разделе мы сделаем небольшой обзор нескольких других типов Python:
Словари
Словари сопоставляют ключи со значениями. Значения могут иметь любое …э-э…значение. Ключи немного более конкретны, но довольно гибки.
>>> d = {} >>> type(d)>>> >>> dir(d) ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] >>> >>> d = {1:2,'a':3, 'c': 'ddddd'} >>> >>> d {1: 2, 'a': 3, 'c': 'ddddd'}
Вы получаете доступ к отдельным значениям по ключу, а не по индексу:
>>> d[0] Traceback (most recent call last): File "", line 1, in KeyError: 0 >>> d[1] 2 >>> d['a'] 3 >>> d['c'] 'ddddd'
Словари, как и списки, изменчивы. Вы можете вносить в них изменения без необходимости создавать совершенно новый диктант. Это означает, что диктанты могут стать жертвами тех же самых ошибок, которые мы уже обсуждали.
>>> d['c'] = 'new value' >>> d {1: 2, 'a': 3, 'c': 'new value'} >>> >>> d['new key'] = 'new value' >>> d {1: 2, 'a': 3, 'new key': 'new value', 'c': 'new value'}
Вы можете указать значения по умолчанию при попытке доступа к значениям из диктанта.
>>> x = d[0] Traceback (most recent call last): File "", line 1, in KeyError: 0 >>> x Traceback (most recent call last): File " ", line 1, in NameError: name 'x' is not defined >>> x = d.get(0) >>> x >>> print(x) None >>> >>> x = d.get(0,"some default") >>> x 'some default'
Для циклов работа немного отличается от списков. В списках цикл for повторяет элементы списка. С помощью dicts он перебирает ключи (а не значения!)
>>> for key in d: ... print(key) ... 1 a new key c >>> for key in d: ... print(key,' : ',d[key]) ... 1 : 2 a : 3 new key : new value c : new value
Наборы
Набор-это неупорядоченная коллекция уникальных элементов:
>>> s = {1,2,3} >>> s {1, 2, 3} >>> type(s)>>> dir(s) ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
Поскольку он неупорядочен, вы не можете получить доступ к элементам по индексу.
>>> s[1] Traceback (most recent call last): File "", line 1, in TypeError: 'set' object does not support indexing
Чтобы добавить вещи в набор, вы используете функцию add
. Это означает, что наборы изменчивы, так же как списки и диктанты:
>>> s {1, 2, 3} >>> s.add(1) >>> s {1, 2, 3} >>> s.add(55) >>> s {1, 2, 3, 55} >>> s.add("parrot") >>> s {1, 2, 3, 'parrot', 55}
Обратите внимание на положение 'parrot'
выше. Помните, что наборы не заботятся о заказе.
Для циклов и оператор in
работают так же для списков, как и для наборов:
>>> for x in s: ... print(x) ... 1 2 3 parrot 55 >>> >>> s {2, 3, 'parrot', 55} >>> 2 in s True >>> 22 in s False >>> 2 not in s False >>> 22 not in s True
Кортежи
Кортежи – это упорядоченные коллекции элементов, но они НЕИЗМЕНЯЕМЫ. Если вы хотите внести изменения в кортеж, вам нужно создать совершенно новый кортеж.
>>> t = (1,2,3) >>> type(t)>>> dir(t) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index'] >>> >>> t (1, 2, 3) >>> t[0] 1 >>> t[1] 2 >>> t[3] Traceback (most recent call last): File " ", line 1, in IndexError: tuple index out of range
Назначение индекса не работает, потому что оно неизменяемо:
>>> t[3] = 'boo' Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment >>> t[2] = 'boo' Traceback (most recent call last): File " ", line 1, in TypeError: 'tuple' object does not support item assignment
Для циклов и в
оператор работает так, как ожидалось.
>>> for x in t: ... print(x) ... 1 2 3 >>> >>> t (1, 2, 3) >>> 1 in t True >>> 111 in t False >>> 1 not in t False >>> 111 not in t True
Дальнейшее чтение
Учебник для начинающих Python: для циклов и итераторов: Я написал это некоторое время назад. Это довольно подробное руководство по итерации в Python. Это старая статья, поэтому она написана для Python2.7, но по большей части она будет отлично работать с Python3.
Зачем вам это читать? Потому что итераторы очень мощные.
Надеюсь, вам понравится.
Вывод
В этой статье подробно рассмотрены списки. Мы рассмотрели основы создания списков, индексации и нарезки. Мы также говорили о изменчивости списков и продемонстрировали несколько не очень интуитивных моделей поведения списков. Затем мы кратко сравнили списки с другими структурами данных. Теперь у вас должны быть инструменты, необходимые для дальнейшего изучения этих структур данных самостоятельно.
Счастливого зацикливания.