Какая разница?
Каковы преимущества / недостатки кортежей / списков?
list
. ; D
Какая разница?
Каковы преимущества / недостатки кортежей / списков?
list
. ; D
Ответы:
Помимо того, что кортежи являются неизменяемыми, существует также семантическое различие, которое должно определять их использование. Кортежи - это гетерогенные структуры данных (т. Е. Их записи имеют разное значение), а списки - это однородные последовательности. Кортежи имеют структуру, списки имеют порядок.
Использование этого различия делает код более явным и понятным.
Одним из примеров могут быть пары страниц и номера строк для ссылок на места в книге, например:
my_location = (42, 11) # page number, line number
Затем вы можете использовать это в качестве ключа в словаре для хранения заметок на местах. Список с другой стороны может быть использован для хранения нескольких мест. Естественно, можно добавить или удалить местоположения из списка, поэтому имеет смысл, что списки изменчивы. С другой стороны, нет смысла добавлять или удалять элементы из существующего местоположения - следовательно, кортежи неизменны.
Могут быть ситуации, когда вы хотите изменить элементы в существующем кортеже местоположения, например, при переборе по строкам страницы. Но неизменность кортежей заставляет вас создавать новый кортеж местоположения для каждого нового значения. На первый взгляд это кажется неудобным, но использование таких неизменяемых данных является краеугольным камнем типов значений и методов функционального программирования, которые могут иметь существенные преимущества.
Есть несколько интересных статей по этому вопросу, например, «Кортежи Python - это не просто списки констант» или «Понимание кортежей и списков в Python» . Официальная документация Python также упоминает это
«Кортежи неизменны и обычно содержат гетерогенную последовательность ...».
В статически типизированном языке, таком как Haskell, значения в кортеже обычно имеют разные типы, и длина кортежа должна быть фиксированной. В списке все значения имеют одинаковый тип, а длина не фиксирована. Так что разница очень очевидна.
Наконец, в Python есть именованный кортеж , который имеет смысл, потому что кортеж уже должен иметь структуру. Это подчеркивает идею, что кортежи являются легкой альтернативой классам и экземплярам.
collections.namedtuple
что лучше бы назвали collections.record
. Нет смысла менять, скажем, имя и адрес в записи клиента; на самом деле, это, как правило, было бы ошибкой, которую неизменность кортежа не позволяет вам совершать.
What would you do with such a list?
меня, я всегда дрожу , когда люди используют отсутствие фантазии в качестве аргумента. Использование списков смешанного типа прекрасно работает, например, для некоторых иерархических структур данных, где каждый список состоит из дочерних списков и элементов-значений.
Разница между списком и кортежем
буквальный
someTuple = (1,2)
someList = [1,2]
Размер
a = tuple(range(1000))
b = list(range(1000))
a.__sizeof__() # 8024
b.__sizeof__() # 9088
Из-за меньшего размера операции кортежа она становится немного быстрее, но не так много, чтобы упоминать, пока у вас не будет огромное количество элементов.
Разрешенные операции
b = [1,2]
b[0] = 3 # [3, 2]
a = (1,2)
a[0] = 3 # Error
Это также означает, что вы не можете удалить элемент или отсортировать кортеж. Однако вы можете добавить новый элемент в список и кортеж с той лишь разницей, что, поскольку кортеж неизменен, вы на самом деле не добавляете элемент, а создаете новый кортеж, поэтому идентификатор изменится
a = (1,2)
b = [1,2]
id(a) # 140230916716520
id(b) # 748527696
a += (3,) # (1, 2, 3)
b += [3] # [1, 2, 3]
id(a) # 140230916878160
id(b) # 748527696
Применение
Поскольку список является изменяемым, его нельзя использовать в качестве ключа в словаре, тогда как кортеж можно использовать.
a = (1,2)
b = [1,2]
c = {a: 1} # OK
c = {b: 1} # Error
3. Permitted operation
показывает регистр кортежей. Я знаю, что обычно показывать успех, а потом ошибаться, но это на несколько мгновений запуталось в моей голове.
one_item_list = [a]
, но one_tuple = (a,)
это соответствующий кортеж. Обратите внимание на запятую после имени переменной. Но также обратите внимание two_tuple = (a, b)
. Это сбило меня с толку не раз (до сих пор в Python 3).
tuple(sorted(the_unsorted_tuple))
Если вы пошли гулять, вы можете записать свои координаты в любой момент в (x,y)
кортеже.
Если вы хотите записать свое путешествие, вы можете добавлять свое местоположение каждые несколько секунд в список.
Но вы не могли сделать это наоборот.
Главное отличие в том, что кортежи неизменны. Это означает, что вы не можете изменить значения в кортеже после его создания.
Поэтому, если вам нужно изменить значения, используйте список.
Преимущества для кортежей:
frozenset
или различные сторонние замороженные dict / tree / etc. типы, но ни один из них не позволяет добавлять изменяемые элементы. (И, конечно, кортеж может быть хэшируемым только в том случае, если все его элементы есть, что обрабатывается обычным способом d[1, [2]]
TypeError: unhashable type: 'list'
Списки изменчивы; кортежей нет.
От docs.python.org/2/tutorial/datastructures.html
Кортежи являются неизменяемыми и обычно содержат гетерогенную последовательность элементов, доступ к которым осуществляется посредством распаковки (см. Далее в этом разделе) или индексации (или даже по атрибуту в случае именованных кортежей). Списки являются изменяемыми, и их элементы обычно однородны и доступны путем итерации по списку.
Было упомянуто, что разница в значительной степени семантическая: люди ожидают, что кортеж и список будут представлять различную информацию. Но это идет дальше, чем руководство; некоторые библиотеки на самом деле ведут себя по-разному в зависимости от того, что они передаются. Возьмем, к примеру, NumPy (скопировано из другого поста, где я прошу больше примеров):
>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
[3, 4, 5]])
Дело в том, что хотя NumPy может и не входить в стандартную библиотеку, это основная библиотека Python, а в списках и кортежах NumPy совершенно разные вещи.
type(a_list) != type(a_tuple)
, что любой фрагмент ветвления кода библиотеки на основе type(x)
будет вести себя по-разному
'%d %d' % [2, 3]
это a TypeError
, потому что вы пытаетесь передать список первому, %d
а вы не передаете никакого значения второму %d
. (Однако есть и контрпримеры к этому, например max
…)
Списки предназначены для зацикливания, кортежи для структур т "%s %s" %tuple
.
Списки обычно однородны, кортежи обычно неоднородны.
Списки для переменной длины, кортежи для фиксированной длины.
Это пример списков Python:
my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]
Это пример кортежа Python:
my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")
Списки и кортежи Python похожи в том, что они оба являются упорядоченными коллекциями значений. Помимо небольшой разницы в том, что списки создаются с использованием скобок «[..., ...]» и кортежей с использованием скобок «(..., ...)», основное техническое отличие «жестко запрограммировано в синтаксисе Python» между ними заключается в том, что элементы определенного кортежа являются неизменяемыми, тогда как списки являются изменяемыми (... поэтому только кортежи могут быть хэшируемыми и могут использоваться в качестве словарных / хэш-ключей!). Это приводит к различиям в том, как они могут или не могут быть использованы (применены априори с помощью синтаксиса), и к различиям в том, как люди выбирают их использование (поощряется как «передовой опыт», апостериорно, это то, что делают умные программисты). люди отдают в порядок элементы.
Для кортежей «порядок» означает не что иное, как определенную «структуру» для хранения информации. Какие значения находятся в первом поле, можно легко переключить во второе поле, поскольку каждое из них предоставляет значения в двух разных измерениях или масштабах. Они дают ответы на различные типы вопросов и обычно имеют форму: для какого объекта / предмета каковы его атрибуты? Объект / субъект остается постоянным, атрибуты различаются.
Для списков «порядок» означает последовательность или направленность. Второй элемент ДОЛЖЕН идти после первого элемента, потому что он расположен на 2-м месте в зависимости от определенной и общей шкалы или измерения. Элементы взяты целиком и в основном дают ответы на один вопрос, как правило, в форме, для данного атрибута, как эти объекты / субъекты сравниваются? Атрибут остается постоянным, объект / тема отличается.
Есть бесчисленные примеры людей в популярной культуре и программистов, которые не соответствуют этим различиям, и есть бесчисленное множество людей, которые могут использовать вилку для салата в качестве основного блюда. В конце концов, все в порядке, и оба обычно могут выполнить свою работу.
Подводя итог некоторых мелких деталей
сходства:
Индексирование, выбор и нарезка - и кортежи, и списки индексируют, используя целочисленные значения в скобках. Итак, если вы хотите первые 3 значения из данного списка или кортежа, синтаксис будет таким же:
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
Сравнение и сортировка - два кортежа или два списка сравниваются по их первому элементу, а если есть связь, то по второму элементу и так далее. Дальнейшее внимание не уделяется последующим элементам после того, как более ранние элементы показывают разницу.
>>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
True
>>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
True
Отличия: - априори по определению
Синтаксис - Списки используют [], кортежи используют ()
Изменчивость - элементы в данном списке являются изменяемыми, элементы в данном кортеже НЕ являются изменяемыми.
# Lists are mutable:
>>> top_rock_list
['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
>>> top_rock_list[1]
'Kashmir'
>>> top_rock_list[1] = "Stairway to Heaven"
>>> top_rock_list
['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
# Tuples are NOT mutable:
>>> celebrity_tuple
('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
>>> celebrity_tuple[5]
'Dead'
>>> celebrity_tuple[5]="Alive"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Хеш-таблицы (словари) - поскольку хеш-таблицы (словари) требуют, чтобы его ключи были хэшируемыми и, следовательно, неизменяемыми, только кортежи могли выступать в качестве ключей словаря, а не списков.
#Lists CAN'T act as keys for hashtables(dictionaries)
>>> my_dict = {[a,b,c]:"some value"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
#Tuples CAN act as keys for hashtables(dictionaries)
>>> my_dict = {("John","Wayne"): 90210}
>>> my_dict
{('John', 'Wayne'): 90210}
Отличия - апостериорные, в использовании
Гомо против гетерогенности элементов - Как правило, объекты списка являются однородными, а объекты кортежей неоднородными. То есть списки используются для объектов / субъектов одного и того же типа (как и все кандидаты в президенты, или все песни, или все бегуны), в то время как хотя это не навязывается), тогда как кортежи больше предназначены для разнородных объектов.
Циклы и структуры - хотя оба допускают циклы (для x в my_list ...), имеет смысл делать это только для списка. Кортежи больше подходят для структурирования и представления информации (% s% s, находящийся в% s, является% s и в настоящее время% s% ("Джон", "Уэйн", 90210, "Актер", "Мертвый"))
Значения списка могут быть изменены в любое время, но значения кортежей не могут быть изменены.
Эти преимущества и недостатки зависят от использования. Если у вас есть такие данные, которые вы никогда не захотите изменить, вам следует использовать кортеж, иначе список - лучший вариант.
Кортежи и списки в Python выглядят как схожие типы последовательностей.
Буквальный синтаксис
Мы используем круглые скобки ( ) для создания кортежей и квадратных скобок,
[ ]
чтобы получить новый список. Также мы можем использовать вызов соответствующего типа, чтобы получить требуемую структуру - кортеж или список.
someTuple = (4,6)
someList = [2,6]
переменчивость
Кортежи неизменны, а списки изменчивы. Этот пункт является основой для следующих.
Использование памяти
Из-за изменчивости вам нужно больше памяти для списков и меньше памяти для кортежей.
простирающийся
Вы можете добавить новый элемент в кортежи и списки с той лишь разницей, что идентификатор кортежа будет изменен (т. Е. У нас будет новый объект).
Хэш
Кортежи могут быть хэшируемыми, а списки - нет. Это означает, что вы можете использовать кортеж в качестве ключа в словаре. Список нельзя использовать в качестве ключа в словаре, тогда как кортеж можно использовать
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
Семантика
Этот пункт больше о лучшей практике. Вы должны использовать кортежи как гетерогенные структуры данных, в то время как списки являются однородными последовательностями.
Списки должны быть однородными последовательностями, а кортежи - гетерогенными структурами данных.
Поскольку люди уже ответили здесь, что tuples
они неизменны lists
, но изменчивы, но есть один важный аспект использования кортежей, который мы должны помнить
Если оно tuple
содержит list
или находится dictionary
внутри, они могут быть изменены, даже если tuple
само является неизменным.
Например, предположим, у нас есть кортеж, который содержит список и словарь в виде
my_tuple = (10,20,30,[40,50],{ 'a' : 10})
мы можем изменить содержимое списка как
my_tuple[3][0] = 400
my_tuple[3][1] = 500
что делает новый кортеж выглядит
(10, 20, 30, [400, 500], {'a': 10})
мы также можем изменить словарь внутри кортежа как
my_tuple[4]['a'] = 500
что сделает общий кортеж выглядит
(10, 20, 30, [400, 500], {'a': 500})
Это происходит потому, что list
и dictionary
объекты, и эти объекты не меняются, а содержимое, на которое оно указывает.
Таким образом, tuple
остается неизменным без каких-либо исключений
PEP 484 - Тип подсказки говорит о том , что типы элементов покрытия tuple
может быть индивидуально набрана; так что вы можете сказать Tuple[str, int, float]
; но a list
, с List
типизацией class может принимать только один параметр типа:, List[str]
который намекает на то, что различие 2 действительно в том, что первый является гетерогенным, тогда как последний по сути однороден.
Кроме того, стандартная библиотека в основном использует кортеж в качестве возвращаемого значения из таких стандартных функций, где C возвращает a struct
.
Поскольку люди уже упоминали различия, я напишу о том, почему кортежи.
Почему кортежи предпочтительнее?
Оптимизация распределения для маленьких кортежей
Чтобы уменьшить фрагментацию памяти и ускорить распределение, Python повторно использует старые кортежи. Если кортеж больше не нужен и содержит менее 20 элементов вместо постоянного удаления, Python перемещает его в свободный список.
Свободный список делится на 20 групп, где каждая группа представляет список кортежей длиной n от 0 до 20. Каждая группа может хранить до 2000 кортежей. Первая (нулевая) группа содержит только 1 элемент и представляет собой пустой кортеж.
>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104
В приведенном выше примере мы видим, что a и b имеют одинаковый идентификатор. Это потому, что мы немедленно заняли уничтоженный кортеж, который был в свободном списке.
Оптимизация размещения для списков
Поскольку списки могут быть изменены, Python не использует такую же оптимизацию, как в кортежах. Однако списки Python также имеют свободный список, но он используется только для пустых объектов. Если пустой список удален или собран GC, он может быть использован позже.
>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792
Источник: https://rushter.com/blog/python-lists-and-tuples/
Почему кортежи эффективнее списков? -> https://stackoverflow.com/a/22140115
Указание направления из документации по 5.3. Кортежи и последовательности :
Хотя кортежи могут показаться похожими на списки, они часто используются в разных ситуациях и для разных целей. Кортежи являются неизменяемыми и обычно содержат гетерогенную последовательность элементов, доступ к которым осуществляется посредством распаковки (см. Далее в этом разделе) или индексации (или даже по атрибуту в случае именованных кортежей). Списки являются изменяемыми , и их элементы обычно однородны и доступны путем итерации по списку.
Прежде всего, они оба являются нескалярными объектами (также известными как составные объекты) в Python.
+
(конечно, будет создан новый кортеж)(3,) # -> (3)
вместо(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
дает вам
[1,4,9,16,25,36]
(не читается)Использование списка также может вызвать ошибку псевдонимов (два разных пути, указывающие на один и тот же объект).
Списки изменчивы, а кортежи неизменны. Просто рассмотрите этот пример.
a = ["1", "2", "ra", "sa"] #list
b = ("1", "2", "ra", "sa") #tuple
Теперь измените значения индекса списка и кортежа.
a[2] = 1000
print a #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b #output : TypeError: 'tuple' object does not support item assignment.
Следовательно, доказано, что следующий код недопустим с кортежем, потому что мы попытались обновить кортеж, что недопустимо.
Список изменчив, а кортежи неизменны. Основное различие между изменяемым и неизменным заключается в использовании памяти при попытке добавить элемент.
При создании переменной некоторая фиксированная память назначается переменной. Если это список, то выделяется больше памяти, чем фактически используется. Например, если текущее назначение памяти составляет 100 байт, когда вы хотите добавить 101-й байт, возможно, будет назначено еще 100 байт (всего 200 байт в этом случае).
Однако, если вы знаете, что вы не часто добавляете новые элементы, вам следует использовать кортежи. Кортежи назначают точно необходимый объем памяти и, следовательно, экономят память, особенно когда вы используете большие блоки памяти.