Яка різниця?
Які переваги / недоліки кортежів / списків?
list
. ; D
Яка різниця?
Які переваги / недоліки кортежів / списків?
list
. ; D
Відповіді:
Окрім того, що кортежі незмінні, існує також семантичне розрізнення, яке має керувати їх використанням. Кортежі - це неоднорідні структури даних (тобто їх записи мають різний зміст), а списки - однорідні послідовності. Кортежі мають структуру, списки мають порядок.
Використання цього розрізнення робить код більш явним і зрозумілим.
Одним із прикладів можуть бути пари номерів сторінки та рядка до посилань на місця в книзі, наприклад:
my_location = (42, 11) # page number, line number
Потім ви можете використовувати це як ключ у словнику для зберігання приміток про місця. Список з іншого боку може бути використаний для зберігання декількох місць. Звичайно, ви можете додати або видалити місця зі списку, тому має сенс, що списки можна змінювати. З іншого боку, немає сенсу додавати або видаляти елементи з існуючого місця - отже, кортежі незмінні.
Можуть виникнути ситуації, коли ви хочете змінити елементи в межах наявного кордону місцеположення, наприклад, під час повторення через рядки сторінки. Але незмінність кортежу змушує вас створювати нове кортеж розташування для кожного нового значення. Це здається незручним для цього, але використання таких змінних даних, як це, є наріжним каменем значущих типів та функціональних методів програмування, які можуть мати суттєві переваги.
У цьому питанні є кілька цікавих статей, наприклад, "кортежі Python - це не просто постійні списки" або "Розуміння кортежів і списків на Python" . Про це згадується і в офіційній документації Python
"Кортежі незмінні і зазвичай містять неоднорідну послідовність ...".
У статично введеній мові, як Haskell, значення в кортежі, як правило, мають різні типи, а довжина кортежу повинна бути фіксована. У списку значення мають однаковий тип, а довжина не фіксована. Тож різниця дуже очевидна.
Нарешті, існує назваtuple в Python, що має сенс, оскільки кортеж уже повинен мати структуру. Це підкреслює думку про те, що кортежі - це легка альтернатива класам та інстанціям.
collections.namedtuple
б краще називати collections.record
. Не було б сенсу міняти, скажімо, ім’я та адресу у записі клієнта; насправді це робиться, як правило, помилкою, яка незмінність кортежа заважає вам здійснити.
What would you do with such a list?
, я завжди тремчу, коли ppl використовує відсутність фантазії як аргумент. Використання списків змішаного типу чудово працює, наприклад, для деяких ієрархічних структур даних, де кожен список складається з дочірніх списків та елементів значення.
Різниця між списком і кортежем
Буквальне
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
або різних заморожених диктантів / дерев / тощо. типів, але жоден із них не дозволяє додавати елементи, що змінюються. (І звичайно, кортеж є хешируемим лише у тому випадку, якщо всі його елементи є, що обробляються звичайним способом EAFP, так 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]
є 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-му місці на основі певного та загального масштабу чи розмірності. Елементи взяті в цілому і в основному дають відповіді на одне запитання, як правило, форми, для даного атрибута, як вони порівнюють ці об’єкти? Атрибут залишається постійним, об'єкт / предмет відрізняється.
Існує незліченна кількість прикладів людей у популярній культурі та програмістів, які не відповідають цим відмінностям, і є незліченна кількість людей, які можуть використовувати салатну вилку для свого основного блюда. Зрештою, це добре, і обидва зазвичай можуть виконати роботу.
Узагальнити деякі тонші деталі
Схожість:
Індексація, вибір та нарізка - індекс як списів, так і списків за допомогою цілих значень, що знаходяться в дужках. Отже, якщо ви хочете, щоб перші три значення даного списку чи кортежу, синтаксис був би таким же:
>>> 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}
Відмінності - a posteriori, у використанні
Гомо проти гетерогенності елементів - загалом перераховують об'єкти однорідні, а кортежні об'єкти - неоднорідні. Тобто списки використовуються для об’єктів / предметів одного типу (як і всі кандидати в президенти, або всі пісні, або всі бігуни), хоча, хоча це не вимушено), тоді як кортежі більше стосуються гетерогенних об'єктів.
Looping vs. Structures - Хоча обидва дозволяють циклічно (для 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
міститься a 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})
ми також можемо змінити словник всередині tuple як
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
клавіші набору тексту можна взяти лише один параметр типу:, List[str]
який натякає, що різниця двох дійсно полягає в тому, що перший є неоднорідним, тоді як другий по суті однорідним.
Крім того, стандартна бібліотека в основному використовує кортеж як зворотне значення з таких стандартних функцій, де 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 байт).
Однак якщо ви знаєте, що не часто додаєте нові елементи, то вам слід використовувати кортежі. Tuples призначає точно потрібний об'єм пам'яті, а значить, економить пам'ять, особливо коли ви використовуєте великі блоки пам'яті.