Вопрос

Сейчас я изучаю Python для класса, и мы только что рассмотрели кортежи как один из типов данных.Я прочитал страницу Википедии, посвященную этому, но я не смог понять, где такой тип данных был бы полезен на практике.Могу ли я привести несколько примеров, возможно, на Python, где потребовался бы неизменяемый набор чисел?Чем это отличается от списка?

Это было полезно?

Решение

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

Другие советы

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

a = {}
a[(1,2,"bob")] = "hello!"
a[("Hello","en-US")] = "Hi There!"

Я использовал эту функцию в первую очередь для создания словаря с ключами, которые являются координатами вершин сетки.Однако в моем конкретном случае точное сравнение задействованных значений с плавающей запятой работало нормально, что не всегда может быть верно для ваших целей [в этом случае я бы, вероятно, преобразовал ваши входящие значения с плавающей запятой в какое-то целое число с фиксированной запятой]

Мне нравится это объяснение.

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

Конечно, всегда есть исключения, но это хорошее общее руководство.

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

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

Типичными примерами являются фиксированные данные в приложении, такие как подразделения компании, категории и т.д.Если эти данные изменяются, обычно один производитель перестраивает кортеж заново.

Лучший способ подумать об этом - это:

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

Поэтому вместо того, чтобы писать что-то вроде:

person = {"name": "Sam", "age": 42}
name, age = person["name"], person["age"]

Или еще более многословный:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("Sam", 42)
name, age = person.name, person.age

Вы можете просто написать:

person = ("Sam", 42)
name, age = person

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

Кортежи происходят из мира функционального программирования (Haskell, OCaml, Elm, F # и т.д.), где они обычно используются для этой цели.В отличие от Python, большинство функциональных языков программирования статически типизированы (переменная может содержать только один тип значения, и этот тип определяется во время компиляции).Статическая типизация делает роль кортежей более очевидной.Например, на языке Elm:

type alias Person = (String, Int)

person : Person
person = ("Sam", 42)

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

Все вышесказанное резко контрастирует со списками, которые должны быть переменной длины (количество элементов обычно разное в каждом списке, и вы пишете функции для добавления и удаления элементов), и каждый элемент в списке обычно одного типа.Например, у вас был бы один список людей и другой список адресов - вы бы не смешивали людей и адреса в одном списке.Принимая во внимание, что смешивание различных типов данных внутри одного и того же кортежа - это весь смысл кортежей.Поля в кортеже обычно бывают разных типов (но не всегда - напримеру тебя мог бы быть (Float, Float, Float) кортеж для представления координат x, y, z).

Кортежи и списки часто являются вложенными. Обычно имеется список кортежей.У вас мог бы быть список кортежей Person точно так же, как и список объектов Person.У вас также может быть поле кортежа, значением которого является список.Например, если у вас есть адресная книга, в которой у одного человека может быть несколько адресов, у вас может быть кортеж типа (Person, [String]).Тот Самый [String] тип обычно используется в функциональных языках программирования для обозначения списка строк.В Python вы бы не записывали тип, но вы могли бы использовать подобные кортежи точно таким же образом, помещая Person объект в первом поле кортежа и список строк в его втором поле.

В Python возникает путаница потому что язык не обеспечивать соблюдение любая из этих практик, которые применяются компилятором в статически типизированных функциональных языках.В этих языках вы не можете смешивать разные типы кортежей.Например, вы не можете вернуть (String, String) кортеж из функции, тип которой говорит о том, что она возвращает (String, Integer) кортеж.Вы также не можете вернуть список, когда в типе указано, что вы планируете вернуть кортеж, и наоборот.Списки используются строго для растущих коллекций элементов, а кортежи - строго для записей фиксированного размера.Python не мешает вам нарушать ни одно из этих правил, если вы этого хотите.

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

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

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

Наконец, чтобы сделать еще более очевидным, что кортежи предназначены для другого вида записей (а не для другого вида списка), Python также имеет именованные кортежи:

from collections import namedtuple

Person = namedtuple("Person", "name age")

person = Person("Sam", 42)
name, age = person.name, person.age

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

Неизменяемые списки очень полезны для многих целей, но эта тема слишком сложна, чтобы отвечать здесь.Главный момент заключается в том, что рассуждать о вещах, которые не могут измениться, легче, чем о вещах, которые могут измениться.Большинство программных ошибок возникают из-за того, что вещи меняются неожиданным образом, поэтому ограничение способов, которыми они могут измениться, является хорошим способом устранения ошибок.Если вам интересно, я рекомендую прочитать учебник по функциональному языку программирования, такому как Elm, Haskell или Clojure (Elm самый дружелюбный).Разработчики этих языков считали неизменяемость настолько полезной , что ВСЕ списки там неизменяемы.(Вместо изменения списка для добавления и/или удаления элемента вы создайте новый список с добавленным или удаленным элементом.Неизменяемость гарантирует, что старая копия списка никогда не сможет измениться, поэтому компилятор и среда выполнения могут обеспечить хорошую производительность кода, повторно используя части старого списка в новом и собирая мусор из оставшихся частей, когда они больше не нужны.)

Я нахожу их полезными, когда вы всегда имеете дело с двумя или более объектами как с набором.

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

Кортеж - это список значений, разделенных запятыми:

t = 'p', 'q', 'r', 's', 't'

хорошей практикой является заключать кортежи в круглые скобки:

t = ('p', 'q', 'r', 's', 't') 

Список всегда может заменить кортеж с точки зрения функциональности (за исключением, по-видимому, использования в качестве ключей в dict).Однако кортеж может ускорить процесс.То же самое верно, например, для неизменяемых строк в Java - когда вам когда-нибудь понадобится не иметь возможности изменять свои строки?Никогда!

Я только что прочитал приличную дискуссию об ограничении того, что вы можете сделать, чтобы создавать лучшие программы; Почему Функциональное программирование Имеет значение

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

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

В дополнение к местам, где они требуются синтаксически, таким как операция string % и для нескольких возвращаемых значений, я использую кортежи как форму облегченных классов.Например, предположим, у вас есть объект, который передает непрозрачный файл cookie вызывающему из одного метода, который затем передается в другой метод.Кортеж - это хороший способ упаковать несколько значений в этот файл cookie без необходимости определять отдельный класс для их хранения.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top