Когда и почему я должен использовать namedtuple вместо словаря?

Возможный дубликат:
Что такое "названные кортежи" в Python?

Какова ситуация с использованием именованного набора?

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

Могут ли использоваться только те же типы хеширования для словарей для namedtuples?

Ответ 1

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

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

В принципе, если вы собираетесь создать кучу экземпляров класса, например:

class Container:
    def __init__(self, name, date, foo, bar):
        self.name = name
        self.date = date
        self.foo = foo
        self.bar = bar

mycontainer = Container(name, date, foo, bar)

и не изменяют атрибуты после того, как вы установили их в __init__,, вместо этого вы можете использовать

Container = namedtuple('Container', ['name', 'date', 'foo', 'bar'])

mycontainer = Container(name, date, foo, bar)

в качестве замены.

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

mynamedtuple.fieldname

лучше, чем

mydict['fieldname']

и

mynamedtuple = MyNamedTuple(firstvalue, secondvalue)

лучше, чем

mydict = {'fieldname': firstvalue, 'secondfield': secondvalue}

Наконец, namedtuple упорядочены, в отличие от обычных dict s, поэтому вы получаете элементы в том порядке, в котором вы определили поля, в отличие от dict.

Ответ 2

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