В чем разница между списками и кортежами в Python? - PullRequest
7 голосов
/ 29 июля 2010

Что является более эффективным? Каково типичное использование каждого?

Ответы [ 4 ]

7 голосов
/ 29 июля 2010

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

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

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

return fee, fie, foo, fum

, то есть возвращать кортеж с четырьмя рассматриваемыми элементами, а не

return [fee, fie, foo, fum]

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

Полезный вариант tuple - это его подтип collection.namedtuple (требуется Python2.6 или выше), что позволяет получить доступ к элементам по имени (с синтаксисом атрибута), а также по индексу (обычный способ).Например, с import collections в верхней части модуля приведенный выше оператор return может стать ...

freturn = collections.namedtuple('freturn', 'fee fie foo fum')

def f():
  ...
return freturn(fee, fie, foo, fum)

Теперь вызывающая сторона f() может использовать свое возвращаемое значение в качествекортеж, как и раньше, но получит хорошие альтернативы, такие как ...:

r = f()
print r.fie

вместо менее понятных и читаемых

print r[1]

Важно отметить, чтоИменованный подкласс кортежа, созданный с помощью collections.namedtuple, по существу не имеет дополнительных издержек по сравнению с непосредственным использованием кортежа, или, как сказано в документации,

они легки и требуют не больше памяти, чем обычные кортежи.1034 *

6 голосов
/ 29 июля 2010

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

Read this .

3 голосов
/ 29 июля 2010

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

1 голос
/ 14 августа 2018

После прочтения Python doc.для встроенных типов я создал таблицу ниже, чтобы показать основные различия между шестью повторяемыми контейнерами.

<code><pre>
Container   Notation     Index [n:m]   Mutable   Hashable
=========   ==========   ===========   =======   ========
String      ' ' or " "    position     Immutable    Yes
Range       range(,,)     position     Immutable    Yes
Tuple       (,)           position     Immutable    Yes
List        [,]           position     Yes          No
Set         {,}           No           Yes          No
Dict        {k:v,k:v}     by key       Yes          No

Поиск быстрее устанавливается и диктуется, потому что они хешируются вместо последовательности и, следовательно, не зависят от размера.Кортеж и список одинаковы, за исключением того, что кортеж является неизменным с меньшим количеством методов, чем список, поэтому он не поддерживает назначение элемента для изменения его содержимого.Но для достижения функциональности «добавления» можно объединить два кортежа, т. Е. t1 += t2.

Поскольку только типы неизменяемых последовательностей поддерживают hash (), list, set и dict нельзя использовать в качестве ключа dict.Это можно легко увидеть ниже, где «a» - это dict последовательность, которая содержит гетеро неизменяемые ключи типов int, float, str, range и tuple:

>>> a
{range(2, 5, 2): 'range', 3: 15, 4.5: 16, 'llmjxm': 'c', -555: 666, -4.5: -25, (5, 6, 7): 'blue', 'abc3': 215, (1, 2, 3): 'red'}
>>> for item in a.keys():
...     print(item, '\t\t==>>', a[item])
... 
range(2, 5, 2)      ==>> range
3       ==>> 15
4.5         ==>> 16
llmjxm      ==>> c
-555        ==>> 666
-4.5        ==>> -25
(5, 6, 7)       ==>> blue
abc3        ==>> 215
(1, 2, 3)       ==>> red
>>> 

, тогда как ключ изменяемого типа приведет к TypeError:

>>> a[{5}] = 56
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> a[[5]] = 56
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> a[{5:6}] = 56
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> a[-555] = 666
>>> 

Подробнее см. link1 и link2 .

...