В чем разница между списками и кортежами в Python?
что более эффективно? Каково типичное использование каждого?
4 ответов
списки-это изменяемые последовательности с множеством методов (как мутирующих, так и не мутирующих), которые чаще всего используются в качестве контейнеров общего назначения (их элементы могут быть объектами любых типов вообще, хотя иногда считается лучшим стилем для списков иметь элементы одного типа или типы, которые будут использоваться эквивалентно).
кортежи-это неизменяемые последовательности с очень небольшим количеством методов (все не мутирующие специальные), которые чаще всего используются, когда вам нужно неизменяемость для использования контейнера в качестве элемента в наборе или ключа в dict (хотя элементы также должны быть неизменяемыми-например, строки, числа или другие вложенные кортежи, чтобы это работало). Их элементы могут быть объектами любых типов, и для кортежей совершенно нормально иметь элементы разных и разных типов.
есть несколько случаев, в которых кортеж или список будут служить так же хорошо, и в таких немногих случаях тот факт, что кортежи немного меньше и быстрее строить можно использовать, чтобы склонить решение в пользу кортежей. Например, когда функция должна возвращать несколько результатов, наиболее нормально использовать
return fee, fie, foo, fum
т. е. верните кортеж с четырьмя рассматриваемыми элементами, а не
return [fee, fie, foo, fum]
т. е. вернуть список с четырьмя элементами - помимо (небольшой прирост) производительности, общая идиома "вернуть Кортеж" также имеет дело с проблемой, что часто возвращаются несколько результатов не одинаковых и взаимозаменяемых типов, поэтому, стилистически говоря, использование списка может считаться более сомнительным выбором.
полезный вариант tuple
является его подтипом коллекций.namedtuple (требуется Python 2.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
не имеет по существу никаких дополнительных накладных расходов по сравнению с использованием кортежа напрямую, или, как говорят документы,
они легкие и не требуется больше памяти, чем обычных кортежей.
список Мутабельный, вы можете добавить элементы к нему. Кортеж не является, что означает, что он (немного) более эффективен. Кортежи тоже hashable, поэтому может быть использован как ключ в словаре.
читать этой.
списки изменчивы (могут быть изменены), кортежи неизменяемы. Типичное использование: это звучит довольно банально, но вы используете списки, когда вам нужно изменить значения. Кортежи, как правило, немного эффективнее из-за их неизменности (если вы не используете их как списки и не дублируете их много...)
после некоторого чтения Python doc. на встроенных типах, Я создал нижеприведенную таблицу, чтобы показать основные различия между шестью итерационными контейнерами.
<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
</pre>
поиск быстрее для set и dict, потому что они хэшируются вместо последовательности и, следовательно, не зависят от размера. Кортеж и список одинаковы, за исключением того, что кортеж неизменяем с меньшим количеством методов, чем список, поэтому он не поддерживает назначение элемента для изменения его содержимого. Но два кортежа могут быть объединены для достижения "добавить" функциональность, т. е. 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 для получения более подробной информации.