As tuplas nomeadas são basicamente tipos de objetos leves e fáceis de criar. As instâncias de tupla nomeadas podem ser referenciadas usando a desreferenciação de variável semelhante a objeto ou a sintaxe de tupla padrão. Eles podem ser usados de maneira semelhante struct
ou outros tipos de registros comuns, exceto que são imutáveis. Eles foram adicionados no Python 2.6 e Python 3.0, embora exista uma receita para implementação no Python 2.4 .
Por exemplo, é comum representar um ponto como uma tupla (x, y)
. Isso leva ao código como o seguinte:
pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
Usando uma tupla nomeada, ela se torna mais legível:
from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
No entanto, tuplas nomeadas ainda são compatíveis com versões anteriores, portanto, o seguinte ainda funcionará:
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)
from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
# use tuple unpacking
x1, y1 = pt1
Portanto, você deve usar tuplas nomeadas em vez de tuplas em qualquer lugar que achar que a notação de objeto tornará seu código mais pitônico e mais facilmente legível . Pessoalmente, comecei a usá-los para representar tipos de valores muito simples, principalmente quando passá-los como parâmetros para funções. Torna as funções mais legíveis, sem ver o contexto da embalagem da tupla.
Além disso, você também pode substituir classes imutáveis comuns que não têm funções , apenas campos com elas. Você pode até usar seus tipos de tupla nomeados como classes base:
class Point(namedtuple('Point', 'x y')):
[...]
No entanto, como nas tuplas, os atributos nas tuplas nomeadas são imutáveis:
>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute
Se você deseja alterar os valores, precisa de outro tipo. Há uma receita útil para tipos de registros mutáveis que permitem definir novos valores para atributos.
>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
2.0
No entanto, não conheço nenhuma forma de "lista nomeada" que permita adicionar novos campos. Você pode apenas querer usar um dicionário nessa situação. As tuplas nomeadas podem ser convertidas em dicionários usando pt1._asdict()
quais retornos {'x': 1.0, 'y': 5.0}
e podem ser operadas com todas as funções usuais do dicionário.
Como já observado, você deve verificar a documentação para obter mais informações a partir da qual esses exemplos foram construídos.
__slots__
typing.NamedTuple
que permite sugestões de tipo e é especialmente conveniente para subclassificar.namedtuple é uma função de fábrica para criar uma classe de tupla. Com essa classe, podemos criar tuplas que podem ser chamadas pelo nome também.
fonte
namedtuple is a factory function for making a tuple class.
essa é provavelmente a única resposta correta aqui: PUma tupla nomeada é uma tupla.
Faz tudo o que uma tupla pode.
Mas é mais do que apenas uma tupla.
É uma subclasse específica de uma tupla criada programaticamente para sua especificação, com campos nomeados e um comprimento fixo.
Isso, por exemplo, cria uma subclasse de tupla e, além de ter um comprimento fixo (neste caso, três), pode ser usado em qualquer lugar em que uma tupla seja usada sem quebrar. Isso é conhecido como substituibilidade de Liskov.
Novidade no Python 3.6 , podemos usar uma definição de classe com
typing.NamedTuple
para criar um nome nomeado:O acima é o mesmo que o abaixo, exceto que o acima tem adicionalmente anotações de tipo e uma sequência de caracteres. A seguir, está disponível no Python 2+:
Isso instancia:
Podemos inspecioná-lo e usar seus atributos:
Explicação mais profunda
Para entender as tuplas nomeadas, primeiro você precisa saber o que é uma tupla. Uma tupla é essencialmente uma lista imutável (não pode ser alterada no local na memória).
Veja como você pode usar uma tupla regular:
Você pode expandir uma tupla com a descompactação iterável:
Tuplas nomeadas são tuplas que permitem que seus elementos sejam acessados por nome em vez de apenas índice!
Você faz um nomeado duplo como este:
Você também pode usar uma única sequência com os nomes separados por espaços, um uso um pouco mais legível da API:
Você pode fazer tudo o que as tuplas podem fazer (veja acima) e fazer o seguinte:
Um comentarista perguntou:
Os tipos que você cria com
namedtuple
são basicamente classes que você pode criar com taquigrafia fácil. Trate-os como aulas. Defina-os no nível do módulo, para que pickle e outros usuários possam encontrá-los.O exemplo de trabalho, no nível global do módulo:
E isso demonstra a falha na pesquisa da definição:
Use-os quando melhorar o seu código para que a semântica dos elementos da tupla seja expressa no seu código.
Você pode usá-los em vez de um objeto, caso contrário, use um objeto com atributos de dados imutáveis e sem funcionalidade.
Você também pode subclassificá-los para adicionar funcionalidade, por exemplo :
Provavelmente seria uma regressão deixar de usar tuplas nomeadas para tuplas. A decisão inicial do projeto concentra-se em saber se o custo do código extra envolvido vale a legibilidade aprimorada quando a tupla é usada.
Não há memória extra usada por tuplas nomeadas versus tuplas.
Você está procurando um objeto com fenda que implemente toda a funcionalidade de uma lista com tamanho estatístico ou uma lista subclassificada que funcione como uma tupla nomeada (e que de alguma forma impeça a alteração de tamanho na lista).
Um exemplo agora expandido, e talvez até substituível de Liskov, do primeiro:
E, para usar, basta subclasse e defina
__slots__
:fonte
nomeduplos são um ótimo recurso, eles são um contêiner perfeito para dados. Quando você precisa "armazenar" dados, você usa tuplas ou dicionários, como:
ou:
A abordagem do dicionário é esmagadora, pois o dict é mutável e mais lento que as tuplas. Por outro lado, as tuplas são imutáveis e leves, mas não têm legibilidade para um grande número de entradas nos campos de dados.
Os nomeados são o compromisso perfeito para as duas abordagens, com grande legibilidade, leveza e imutabilidade (além de serem polimórficos!).
fonte
ntuple.foo
vsntuple[1]
o último é muito mais rápido. Mais sobre isso: stackoverflow.com/questions/2646157/…tuplas nomeadas permitem compatibilidade com versões anteriores com código que verifica a versão como esta
permitindo que o código futuro seja mais explícito usando esta sintaxe
fonte
nomeado
é uma das maneiras mais fáceis de limpar seu código e torná-lo mais legível. Ele auto-documenta o que está acontecendo na tupla. As instâncias de nomes nomeados são tão eficientes na memória quanto as tuplas regulares, pois não possuem dicionários por instância, tornando-os mais rápidos que os dicionários.
Sem nomear cada elemento na tupla, ele seria assim:
É muito mais difícil entender o que está acontecendo no primeiro exemplo. Com um nomeado duplo, cada campo tem um nome. E você acessa-o pelo nome, em vez de posição ou índice. Em vez de
p[1]
, podemos chamá-lo de p.saturation. É mais fácil de entender. E parece mais limpo.Criar uma instância do nome nomeado é mais fácil do que criar um dicionário.
Quando você pode usar o nomeado duplo
p.hue
ao invés dep['hue']
.A sintaxe
['x', 'y', 'z']
ou stringx y z
(sem vírgulas, apenas espaço em branco) oux, y, z
.True
, nomes de campo inválidos são substituídos automaticamente por nomes posicionais. Por exemplo,['abc', 'def', 'ghi','abc']
é convertido em['abc', '_1', 'ghi', '_3']
, eliminando a palavra-chave'def'
(já que é uma palavra reservada para definir funções) e o nome do campo duplicado'abc'
.True
, a definição da classe será impressa imediatamente antes de ser criada.Você ainda pode acessar os nomeados por sua posição, se assim desejar.
p[1] == p.saturation
. Ele ainda é descompactado como uma tupla comum.Métodos
Todos os métodos regulares de tupla são suportados. Ex: min (), max (), len (), in, não in, concatenação (+), índice, fatia, etc. E existem alguns adicionais para o nomeado duplo. Nota: todos eles começam com um sublinhado.
_replace
,_make
,_asdict
._replace
Retorna uma nova instância da tupla nomeada, substituindo os campos especificados por novos valores.A sintaxe
Exemplo
Aviso : Os nomes dos campos não estão entre aspas; são palavras-chave aqui. Lembre - se : as tuplas são imutáveis - mesmo que tenham nomes de nomeados e tenham o
_replace
método. O_replace
produz umanew
instância; não modifica o original nem substitui o valor antigo. Obviamente, você pode salvar o novo resultado na variável.p = p._replace(hue=169)
_make
Torna uma nova instância de uma sequência existente ou iterável.
A sintaxe
Exemplo
O que aconteceu com o último? O item entre parênteses deve ser iterável. Portanto, uma lista ou tupla entre parênteses funciona, mas a sequência de valores sem incluir como iterável retorna um erro.
_asdict
Retorna um novo OrderedDict que mapeia os nomes dos campos para seus valores correspondentes.
A sintaxe
Exemplo
Referência : https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/
Também existe uma lista nomeada, semelhante à tupla nomeada, mas mutável https://pypi.python.org/pypi/namedlist
fonte
_
!O que é nomeado duplo?
Como o nome sugere, namedtuple é uma tupla com nome. Na tupla padrão, acessamos os elementos usando o índice, enquanto o namedtuple permite ao usuário definir o nome dos elementos. Isso é muito útil, especialmente o processamento de arquivos csv (valor separado por vírgula) e o trabalho com conjuntos de dados grandes e complexos, nos quais o código fica confuso com o uso de índices (não tão pitonicos).
Como usá-los?
Lendo
Cenário interessante no processamento de CSV:
fonte
No Python interno, existe um bom uso do contêiner chamado tupla nomeada, que pode ser usada para criar uma definição de classe e possui todos os recursos da tupla original.
O uso da tupla nomeada será aplicado diretamente ao modelo de classe padrão para gerar uma classe simples, esse método permite muito código para melhorar a legibilidade e também é muito conveniente ao definir uma classe.
fonte
Outra maneira (uma nova maneira) de usar tupla nomeada é usar NamedTuple ao digitar o pacote: Digite dicas no namedtuple
Vamos usar o exemplo da resposta principal neste post para ver como usá-lo.
(1) Antes de usar a tupla nomeada, o código é assim:
(2) Agora usamos a tupla nomeada
herdar a classe NamedTuple e definir o nome da variável na nova classe. test é o nome da classe.
crie instâncias da classe e atribua valores a elas
use as variáveis das instâncias para calcular
fonte
Tente o seguinte:
Basicamente,
namedtuples
são fáceis de criar, tipos de objetos leves. Eles transformam tuplas em recipientes convenientes para tarefas simples. Comnamedtuples
, você não precisa usar índices inteiros para acessar membros de uma tupla.Exemplos:
Código 1:
Código 2:
fonte
Todo mundo já respondeu, mas acho que ainda tenho mais alguma coisa a acrescentar.
O nome nomeado pode ser considerado intuitivamente como um atalho para definir uma classe.
Veja uma maneira complicada e convencional de definir a
class
.Quanto a
namedtuple
fonte
red_duck[0]
oulen(red_duck)
oufor x in red_duck: print(x)
. Além disso, as tuplas nomeadas são imutáveis, portanto, essas operações falharão:red_duck[0] = 2
,red_duck.foo = 'bar'
. Por serem imutáveis, as tuplas nomeadas podem ser usadas comodict
chaves.