В чем разница между списками и кортежами?

885

Какая разница?

В чем преимущества/недостатки кортежей/списков?

  • 13
    Другие ответили ниже, но я хотел бы отметить, что, imho, в python есть совершенно не интуитивные имена типов данных. Я не думаю, что у любого другого языка есть кортежи (с таким названием), и что еще хуже, как слово, которое я даже не могу перевести на мой язык. Кто-нибудь знает, откуда взялся «кортеж»? Голландский ?
  • 88
    Кортежи - это базовый термин в математике, образованный от латинского языка (см. Википедию).
Показать ещё 6 комментариев
Теги:
list
tuples

19 ответов

923
Лучший ответ

Помимо неизменности кортежей, существует также семантическое различие, которое должно служить руководством для их использования. Кортежи представляют собой разнородные структуры данных (т.е. Их записи имеют разные значения), а списки - однородные последовательности. Кортежи имеют структуру, списки имеют порядок.

Использование этого различия делает код более явным и понятным.

В качестве примера можно привести пары номеров страниц и строк для ссылок в книге, например:

my_location = (42, 11)  # page number, line number

Затем вы можете использовать это как ключ в словаре для хранения заметок на местах. С другой стороны, список можно использовать для хранения нескольких местоположений. Естественно, можно захотеть добавить или удалить местоположения из списка, поэтому имеет смысл, что списки изменяемы. С другой стороны, нет смысла добавлять или удалять элементы из существующего местоположения, поэтому кортежи неизменяемы.

Могут быть ситуации, когда вы хотите изменить элементы в существующем кортеже места, например, при повторении по строкам страницы. Но неизменность кортежа заставляет вас создавать новый кортеж для каждого нового значения. Это кажется неудобным на первый взгляд, но использование неизменных данных, подобных этому, является краеугольным камнем типов значений и методов функционального программирования, которые могут иметь существенные преимущества.

Есть несколько интересных статей по этой проблеме, например: "Кортежи Python - это не просто списки констант" или "Понимание кортежей и списков в Python". Официальная документация Python также упоминает это

"Кортежи неизменяемы и обычно содержат гетерогенную последовательность...".

На статически типизированном языке, таком как Haskell, значения в кортеже обычно имеют разные типы и длина кортежа должна быть исправлена. В списке все значения имеют один и тот же тип, а длина не фиксирована. Поэтому разница очень очевидна.

Наконец, в Python есть namedtuple, что имеет смысл, поскольку кортеж уже должен иметь структуру. Это подчеркивает мысль о том, что кортежи представляют собой легкую альтернативу классам и экземплярам.

  • 11
    +1, особенно для вашей второй ссылки с отличным примером. Люблю эту цитату: «Этот кортеж функционирует как легкая запись или структура».
  • 91
    «списки - это однородные последовательности» - я новичок в Python, но не являются ли списки неоднородными? Из docs.python.org/py3k/tutorial/introduction.html : «Не все элементы списка должны иметь одинаковый тип». Но, возможно, вы говорите о формальной концепции, а не о Python.
Показать ещё 21 комментарий
309

Разница между списком и кортежем

  • Буквенный

    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
    
  • 0
    Так что же происходит, когда я пытаюсь изменить размер списка на большие значения? Будет ли это изменить адрес памяти (который я считаю, должен изменить идентификатор). Или это выдаст мне ошибку?
  • 12
    @WanderingMind: адрес памяти, где хранятся значения списка, не совпадает с адресом памяти, где хранится сам объект списка.
Показать ещё 3 комментария
183

Если вы отправились на прогулку, вы могли бы отметить ваши координаты в любой момент в корте (x,y).

Если вы хотите записать свое путешествие, вы можете добавить свое местоположение каждые несколько секунд в список.

Но ты не мог сделать это наоборот.

  • 32
    Этот пример выглядит просто как соглашение. Люди могут возразить: «Я все еще могу использовать [x, y], чтобы отмечать координаты, если я хочу». Таким образом, этот ответ считается незавершенным, если не добавить еще одно предложение: «Прочтите сообщение @nikow, почему вы не должны использовать список для хранения координат»
  • 64
    @ Айсберг, мой ответ призван помочь развить интуицию. Это не предназначено, чтобы исследовать каждый нюанс темы.
Показать ещё 2 комментария
75

Ключевым отличием является то, что кортежи неизменяемы. Это означает, что вы не можете изменить значения в кортеже после его создания.

Итак, если вам нужно изменить значения, используйте List.

Преимущества для кортежей:

  • Небольшое улучшение производительности.
  • Поскольку кортеж является неизменным, он может использоваться как ключ в словаре.
  • Если вы не можете его изменить, ни один другой не может сказать, что вам не нужно беспокоиться о каких-либо функциях API и т.д., изменяя свой кортеж, не спрашивая.
  • 14
    Обратите внимание, что кортеж является неизменным, только если все его элементы . Можно сказать, что то же самое верно для всех неизменных коллекций, таких как frozenset или различные сторонние замороженные dict / tree / etc. типы, но ни один из них не позволяет добавлять изменяемые элементы. (И, конечно, кортеж может быть хэшируемым только в том случае, если все его элементы есть, что обрабатывается обычным способом EAFP, поэтому d[1, [2]] вызовет TypeError: unhashable type: 'list' .)
  • 1
    Кортеж может использоваться в качестве ключа в словаре, только если все его элементы являются неизменяемыми. Смотрите здесь
32

Списки изменяются; Кортежи не являются.

От docs.python.org/2/tutorial/datastructures.html

Кортежи неизменяемы и обычно содержат гетерогенную последовательность элементы, к которым осуществляется доступ через распаковку (см. далее в этом разделе) или индексирование (или даже атрибут в случае namedtuples). Списки являются изменяемыми, а их элементы обычно однородны и являются доступ через итерирование по списку.

  • 1
    Я действительно думаю, что вы также должны учитывать семантические значения (см. Мой ответ ниже).
  • 1
    D'о! Я постараюсь сделать лучше в следующий раз ...
Показать ещё 11 комментариев
18

Было отмечено , что разница в значительной степени семантическая: люди ожидают, что кортеж и список будут представлять различную информацию. Но это идет дальше, чем руководство; некоторые библиотеки фактически ведут себя по-разному на основе того, что они передают. Возьмите 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 и кортежах совершенно разные вещи.

  • 2
    Это не очень полезный ответ. Разница в том, что type(a_list) != type(a_tuple) , поэтому любой фрагмент ветвления кода библиотеки, основанный на type(x) будет вести себя по-разному
  • 1
    Хорошо, что я отредактировал пост: на самом деле это просто указание на то, что семантические рекомендации жестко закодированы в некоторых библиотеках.
Показать ещё 2 комментария
18

Списки для циклизации, кортежи для структур, т.е. "%s %s" %tuple.

Списки обычно однородны, кортежи обычно неоднородны.

Списки для переменной длины, кортежи для фиксированной длины.

14

Это пример списков 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", разница между ними состоит в том, что элементы определенного кортежа являются неизменяемыми, тогда как списки являются изменяемыми (... поэтому только кортежи являются хешируемыми и могут использоваться как ключи словаря/хэша!). Это приводит к различиям в том, как они могут или не могут быть использованы (усилены априорно по синтаксису) и различиям в том, как люди предпочитают их использовать (поощряемые как "лучшие практики", апостериор, это то, что делают умные программисты). Основное различие апостериор в дифференцировании при использовании кортежей в сравнении с используемыми списками заключается в том, что люди дают порядку элементов.

Для кортежей "порядок" означает не что иное, как просто определенную "структуру" для хранения информации. Какие значения находятся в первом поле, можно легко переключить во второе поле, поскольку каждый из них дает значения в двух разных измерениях или масштабах. Они дают ответы на различные типы вопросов и обычно имеют форму: для данного объекта/предмета, каковы его атрибуты? Объект/объект остается постоянным, атрибуты отличаются.

Для списков "порядок" означает последовательность или направленность. Второй элемент ДОЛЖЕН прибыть после первого элемента, потому что он позиционируется во втором месте на основе конкретного и общего масштаба или измерения. Элементы берутся в целом и в основном дают ответы на один вопрос, типично формы, для данного атрибута, как эти объекты/предметы сравниваются? Атрибут остается постоянным, объект/объект отличается.

Есть бесчисленные примеры людей в популярной культуре и программистах, которые не соответствуют этим различиям, и есть бесчисленные люди, которые могут использовать салатную вилку для своего основного курса. В конце концов, это нормально, и оба могут обычно выполнять свою работу.

Чтобы обобщить некоторые более тонкие детали

Сходства:

  • Дубликаты. Оба кортежа и списки допускают дубликаты.
  • Индексирование, выбор и разбиение на разделы - как кортежи, так и списки индексов с использованием целочисленных значений, найденных в скобках. Итак, если вы хотите получить первые 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
    

Различия: - априори, по определению

  • Синтаксис - списки используют [], кортежи use()

  • Mutability - Элементы в данном списке изменяемы, элементы в данном наборе НЕ изменяемы.

    # 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
    
  • Hashtables (словари). Поскольку hashtables (словари) требуют, чтобы его ключи были хешируемыми и поэтому неизменяемыми, только кортежи могут действовать как словарные ключи, а не списки.

    #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}
    

Различия - апостериор, в использовании

  • Гомо и гетерогенность элементов. Обычно объекты списка однородны, а кортежи - гетерогенные. То есть, списки используются для объектов/предметов того же типа (например, всех кандидатов в президенты, или всех песен, или всех бегунов), хотя, хотя это и не принудительно), в то время как кортежи больше подходят для гетерогенных объектов.

  • Looping vs. Structures. Хотя оба позволяют цикл (для x в my_list...), действительно имеет смысл сделать это для списка. Корреспонденты более подходят для структурирования и представления информации (% s% s, проживающих в% s,% s и в настоящее время% s% ( "Джон", "Уэйн", 90210, "Актер", "Мертвый" ))

  • 0
    Мне нравится пример hashtable / hashable для объяснения причины неизменности - вы можете использовать кортеж (запись / структура / координата / вектор / точка) как сложный ключ в dict.
9

Значения list могут быть изменены в любое время, но значения кортежей не могут быть изменены.

Преимущества и недостатки зависят от использования. Если у вас есть такие данные, которые вы никогда не захотите менять, вам придется использовать кортеж, иначе список - лучший вариант.

7

Разница между списком и кортежем

Кортежи и списки являются, по-видимому, похожими типами последовательностей в Python.

  1. Литеральный синтаксис

    Мы используем скобки (), чтобы построить кортежи и квадратные скобки [ ] чтобы получить новый список. Кроме того, мы можем использовать вызов соответствующего типа, чтобы получить требуемую структуру - кортеж или список.

    someTuple = (4,6)
    someList  = [2,6] 
    
  2. переменчивость

    Кортежи неизменяемы, а списки изменяемы. Эта точка является основой для следующих.

  3. Использование памяти

    Из-за изменчивости вам нужно больше памяти для списков и меньше памяти для кортежей.

  4. простирающийся

    Вы можете добавить новый элемент как к кортежам, так и к спискам с той лишь разницей, что идентификатор кортежа будет изменен (т.е. Будет иметь новый объект).

  5. хеширования

    Кортежи хешируются, а списков нет. Это означает, что вы можете использовать кортеж в качестве ключа в словаре. Список не может использоваться как ключ в словаре, тогда как кортеж может использоваться

    tup      = (1,2)
    list_    = [1,2] 
    
    c = {tup   : 1}     # ok
    c = {list_ : 1}     # error
    
  6. Семантика

    Этот момент больше посвящен лучшей практике. Вы должны использовать кортежи как гетерогенные структуры данных, а списки - однородные последовательности.

  • 1
    Мой голос здесь за явное обсуждение расширения и хеширования, которое я не заметил в других очень хороших существующих ответах.
6

Списки предназначены для однородных последовательностей, а кортежи - это разнородные структуры данных.

  • 23
    На данный момент этот ответ ничего не добавляет к обсуждению, так как есть много других лучших ответов.
3

PEP 484 - подсказки типа говорит, что типы элементов tuple могут быть индивидуально напечатаны; так что вы можете сказать Tuple[str, int, float]; но list, с классом list для ввода может принимать только один параметр типа: List[str], который намекает на то, что различие 2 действительно состоит в том, что первое является гетерогенным, тогда как последнее по своей сути однородно.

Кроме того, стандартная библиотека в основном использует кортеж как возвращаемое значение из таких стандартных функций, где C вернет a struct.

2

Поскольку люди уже ответили здесь, что 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 остается неизменным без каких-либо исключений

  • 0
    Этот пост был бы улучшен, если бы вы объяснили, что «их можно изменить, даже если сам кортеж неизменен». потому что эти объекты сохраняют свою идентичность в то время как (поэтому кортеж не изменился, потому что он все еще содержит те же объекты ...).
2

цитата из документации по 5.3. Кортежи и последовательности:

Хотя кортежи могут казаться похожими на списки, они часто используются в разных ситуациях и для разных целей. Кортежи неизменяемы и обычно содержат гетерогенную последовательность элементов, к которым осуществляется доступ через распаковку (см. Далее в этом разделе) или индексирование (или даже атрибут в случае namedtuples). Списки изменяются, и их элементы обычно однородны и к ним обращаются путем повторения списка.

1

Прежде всего, они оба являются нескалярными объектами (также называемыми составными объектами) в Python.

  • Кортежи, упорядоченная последовательность элементов (которая может содержать любой объект без проблемы с псевдонимом)
    • Неизменяемый (tuple, int, float, str)
    • Конкатенация с использованием + (конечно же, будет создан новый кортеж)
    • Индексация
    • Нарезка
    • Синглтон (3,) # -> (3) вместо (3) # -> 3
  • Список (массив на других языках), упорядоченная последовательность значений
    • Mutable
    • Singleton [3]
    • Клонирование new_array = origin_array[:]
    • Понимание списка [x**2 for x in range(1,7)] дает вам [1,4,9,16,25,36] (Не читается)

Использование списка также может вызвать ошибку псевдонимов (два разных пути указывая на тот же объект).

0

Списки и кортежи хранят один или несколько объектов или значений в определенном порядке. Объекты, хранящиеся в списке или кортеже, могут быть любого типа, включая тип ничего, определяемый ключевым словом "Нет".

Различия в синтаксисе

Синтаксис списка и кортежа несколько отличается. Списки окружены квадратными скобками [], а кортежи окружены скобкой().

Пример 1.1: Создание списка или создание кортежа

list_num = [1,2,3,4]
tup_num = (1,2,3,4)

print(list_num)
print(tup_num)

Выход:

[1,2,3,4]
(1,2,3,4)

Переменный список против неизменяемых кортежей

Список имеет изменчивый характер, т.е. Список может быть изменен или изменен после его создания в соответствии с потребностями, тогда как кортеж имеет неизменный характер, т.е. Кортеж не может быть изменен или изменен после его создания.

Пример 2.1: Изменить список элементов по сравнению с кортежем

list_num[2] = 5
print(list_num)

tup_num[2] = 5

Выход:

[1,2,5,4]
Traceback (most recent call last): 
 File "python", line 6, in <module> 
TypeError: 'tuple' object does not support item assignment

Доступные операции

Списки имеют больше встроенной функции, чем функция кортежа. Мы можем использовать встроенную функцию dir ([object]) для получения всех связанных функций для списка и кортежа.

Пример 3.1: Список каталогов

dir(list_num)
dir(tup_num)

Сравнение размеров

Операция надрядов имеет меньший размер, чем список, что делает его немного быстрее, но не так много, чтобы упомянуть о нем до тех пор, пока у вас не будет огромного количества элементов.

Пример 5.1: Вычислить размер списка по сравнению с кортежем

a= (1,2,3,4,5,6,7,8,9,0)
b= [1,2,3,4,5,6,7,8,9,0]

print('a=',a.__sizeof__())
print('b=',b.__sizeof__())

Выход:

a= 104
b= 120

Различные случаи использования

  • На первый взгляд может показаться, что списки всегда могут заменять кортежи. Но кортежи - чрезвычайно полезные структуры данных
  • Использование кортежа вместо списка может дать программисту и интерпретатору намек на то, что данные не должны быть изменены.
  • Кортежи обычно используются как эквивалент словаря без ключей для хранения данных.

Ключевые моменты, которые следует помнить:

  • Литеральный синтаксис кортежей показан скобками(), тогда как литеральный синтаксис списков показан квадратными скобками [].
  • Списки имеют переменную длину, кортеж имеет фиксированную длину.
  • Список имеет изменчивую природу, кортеж имеет неизменную природу.
  • Список имеет больше функциональности, чем кортеж.
0

Основное различие, которое я обнаружил, состоит в том, что списки изменяемы, когда кортежи неизменяемы. Кортежи хороши для вычислений, в которых их не нужно менять.

  • 3
    Что нужно добавить к принятому ответу?
0

Списки изменяемы, а кортежи неизменяемы. Просто рассмотрите этот пример.

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.

Следовательно, доказал, что следующий код недействителен с кортежем, потому что мы попытались обновить кортеж, который не разрешен.

-1

Список является изменяемым, а кортежи неизменяемы. Основное различие между изменяемыми и неизменяемыми - использование памяти при попытке добавить элемент.

При создании переменной фиксированная память назначается переменной. Если это список, больше памяти назначается, чем фактически используется. Например. если текущее присвоение памяти составляет 100 байт, если вы хотите добавить 101-й байт, возможно, потребуется еще 100 байт (в этом случае всего 200 байт).

Однако, если вы знаете, что вы не часто добавляете новые элементы, вам следует использовать кортежи. Кортежи назначают точно размер необходимой памяти и, следовательно, экономит память, особенно когда вы используете большие блоки памяти.

  • 2
    Хотя это технически верно, но на самом деле это не принципиальное различие между изменяемыми и неизменяемыми типами. Большая разница в том, что изменяемые типы могут быть изменены после создания, в то время как неизменяемые типы не могут.
  • 1
    Это тоже не то, почему. Память и изменчивость не имеют ничего общего друг с другом. Это просто детали реализации, специфичные для списков. Память также не присваивается переменным, она присваивается объектам. Переменные - это просто ссылки на эти объекты.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню