Las tuplas con nombre son básicamente tipos de objetos livianos y fáciles de crear. Se puede hacer referencia a las instancias de tupla con nombre utilizando la desreferenciación de variables tipo objeto o la sintaxis de tupla estándar. Se pueden usar de manera similar struct
u otros tipos de registros comunes, excepto que son inmutables. Se agregaron en Python 2.6 y Python 3.0, aunque hay una receta para la implementación en Python 2.4 .
Por ejemplo, es común representar un punto como una tupla (x, y)
. Esto lleva a un código como el siguiente:
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 una tupla nombrada se vuelve más legible:
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)
Sin embargo, las tuplas con nombre siguen siendo compatibles con las tuplas normales, por lo que lo siguiente seguirá funcionando:
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
Por lo tanto, debe usar tuplas con nombre en lugar de tuplas en cualquier lugar donde piense que la notación de objetos hará que su código sea más pitónico y más fácil de leer . Personalmente, comencé a usarlos para representar tipos de valores muy simples, particularmente al pasarlos como parámetros a funciones. Hace que las funciones sean más legibles, sin ver el contexto del empaquetado de tuplas.
Además, también puede reemplazar las clases inmutables ordinarias que no tienen funciones , solo campos con ellas. Incluso puede usar sus tipos de tuplas con nombre como clases base:
class Point(namedtuple('Point', 'x y')):
[...]
Sin embargo, como con las tuplas, los atributos en las tuplas nombradas son inmutables:
>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute
Si desea poder cambiar los valores, necesita otro tipo. Hay una práctica receta para tipos de registro mutables que le permiten establecer nuevos valores en los 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
Sin embargo, no conozco ninguna forma de "lista con nombre" que le permita agregar nuevos campos. Es posible que solo desee utilizar un diccionario en esta situación. Las tuplas con nombre se pueden convertir a diccionarios utilizando los pt1._asdict()
retornos {'x': 1.0, 'y': 5.0}
y se puede operar con todas las funciones habituales del diccionario.
Como ya se señaló, debe consultar la documentación para obtener más información a partir de la cual se construyeron estos ejemplos.
__slots__
typing.NamedTuple
sugerencias de tipo y es especialmente conveniente para la subclasificación.nombre de tupla es una función de fábrica para hacer una clase de tupla. Con esa clase también podemos crear tuplas que se pueden llamar por nombre.
fuente
namedtuple is a factory function for making a tuple class.
esa es probablemente la única respuesta correcta aquí: PUna tupla nombrada es una tupla.
Hace todo lo que una tupla puede.
Pero es más que una simple tupla.
Es una subclase específica de una tupla que se crea mediante programación según sus especificaciones, con campos con nombre y una longitud fija.
Esto, por ejemplo, crea una subclase de tupla, y además de ser de longitud fija (en este caso, tres), se puede usar en todas partes donde se usa una tupla sin romperse. Esto se conoce como la sustituibilidad de Liskov.
Nuevo en Python 3.6 , podemos usar una definición de clase
typing.NamedTuple
para crear una tupla nombrada:Lo anterior es lo mismo que a continuación, excepto que lo anterior también tiene anotaciones de tipo y una cadena de documentos. Lo siguiente está disponible en Python 2+:
Esto lo instancia:
Podemos inspeccionarlo y usar sus atributos:
Explicación más profunda
Para comprender las tuplas con nombre, primero debe saber qué es una tupla. Una tupla es esencialmente una lista inmutable (no se puede cambiar in situ en la memoria).
Así es como puedes usar una tupla regular:
Puede expandir una tupla con desempaquetado iterable:
Las tuplas con nombre son tuplas que permiten acceder a sus elementos por nombre en lugar de solo índice.
Haces una tupla nombrada así:
También puede usar una sola cadena con los nombres separados por espacios, un uso ligeramente más legible de la API:
Puedes hacer todo lo que las tuplas pueden hacer (ver arriba) así como hacer lo siguiente:
Un comentarista preguntó:
Los tipos que creas con
namedtuple
son básicamente clases que puede crear con una taquigrafía fácil. Trátelos como clases. Defínalos en el nivel del módulo, para que Pickle y otros usuarios puedan encontrarlos.El ejemplo de trabajo, a nivel de módulo global:
Y esto demuestra la imposibilidad de buscar la definición:
Úselos cuando mejore su código para tener la semántica de los elementos de tupla expresados en su código.
Puede usarlos en lugar de un objeto si de otro modo usaría un objeto con atributos de datos inmutables y sin funcionalidad.
También puede subclasificarlos para agregar funcionalidad, por ejemplo :
Probablemente sería una regresión cambiar de usar tuplas con nombre a tuplas. La decisión de diseño inicial se centra en si el costo del código adicional involucrado vale la legibilidad mejorada cuando se usa la tupla.
No hay memoria adicional utilizada por tuplas con nombre versus tuplas.
Está buscando un objeto ranurado que implemente toda la funcionalidad de una lista de tamaño estático o una lista subclasificada que funciona como una tupla con nombre (y que de alguna manera bloquea el cambio de tamaño de la lista).
Un ejemplo ahora ampliado, y tal vez incluso sustituible de Liskov, del primero:
Y para usar, solo subclase y defina
__slots__
:fuente
namedtuples son una gran característica, son contenedores perfectos para datos. Cuando tiene que "almacenar" datos, usaría tuplas o diccionarios, como:
o:
El enfoque del diccionario es abrumador, ya que los dict son mutables y más lentos que las tuplas. Por otro lado, las tuplas son inmutables y livianas, pero carecen de legibilidad para una gran cantidad de entradas en los campos de datos.
namedtuples son el compromiso perfecto para los dos enfoques, tienen una gran legibilidad, ligereza e inmutabilidad (¡además son polimórficos!).
fuente
ntuple.foo
vsntuple[1]
este último es mucho más rápido. Más sobre esto: stackoverflow.com/questions/2646157/…las tuplas con nombre permiten la compatibilidad con el código que verifica la versión como esta
al tiempo que permite que el código futuro sea más explícito al usar esta sintaxis
fuente
nombre de tupla
es una de las formas más fáciles de limpiar su código y hacerlo más legible. Auto-documenta lo que está sucediendo en la tupla. Las instancias de Namedtuples son tan eficientes en memoria como las tuplas normales, ya que no tienen diccionarios por instancia, lo que las hace más rápidas que los diccionarios.
Sin nombrar cada elemento en la tupla, se leería así:
Es mucho más difícil entender lo que está sucediendo en el primer ejemplo. Con una tupla nombrada, cada campo tiene un nombre. Y accede a él por nombre en lugar de posición o índice. En lugar de
p[1]
, podemos llamarlo p.saturation. Es más fácil de entender. Y se ve más limpio.Crear una instancia de namedtuple es más fácil que crear un diccionario.
¿Cuándo podrías usar namedtuple?
p.hue
en lugar dep['hue']
.La sintaxis
['x', 'y', 'z']
o cadenax y z
(sin comas, solo espacios en blanco) ox, y, z
.True
, los nombres de campo no válidos se reemplazan automáticamente con nombres posicionales. Por ejemplo,['abc', 'def', 'ghi','abc']
se convierte a['abc', '_1', 'ghi', '_3']
, eliminando la palabra clave'def'
(ya que es una palabra reservada para definir funciones) y el nombre de campo duplicado'abc'
.True
, la definición de clase se imprime justo antes de ser construida.Todavía puede acceder a las tuplas nombradas por su posición, si así lo desea.
p[1] == p.saturation
. Todavía se desempaqueta como una tupla normal.Métodos
Todos los métodos regulares de tupla son compatibles. Ej: min (), max (), len (), in, not in, concatenation (+), index, slice, etc. Y hay algunos adicionales para namedtuple. Nota: todo esto comienza con un guión bajo.
_replace
,_make
,_asdict
._replace
Devuelve una nueva instancia de la tupla nombrada que reemplaza los campos especificados con nuevos valores.La sintaxis
Ejemplo
Aviso : los nombres de campo no están entre comillas; Son palabras clave aquí. Recuerde : las tuplas son inmutables, incluso si se llaman tuplas y tienen el
_replace
método. El_replace
produce unanew
instancia; no modifica el original ni reemplaza el valor anterior. Por supuesto, puede guardar el nuevo resultado en la variable.p = p._replace(hue=169)
_make
Crea una nueva instancia a partir de una secuencia existente o iterable.
La sintaxis
Ejemplo
¿Qué pasó con el último? El elemento dentro del paréntesis debe ser iterable. Entonces, una lista o tupla dentro del paréntesis funciona, pero la secuencia de valores sin encerrarse como iterable devuelve un error.
_asdict
Devuelve un nuevo OrderedDict que asigna nombres de campo a sus valores correspondientes.
La sintaxis
Ejemplo
Referencia : https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/
También hay una lista con nombre que es similar a la tupla con nombre pero mutable https://pypi.python.org/pypi/namedlist
fuente
_
!¿Qué se llama tupla?
Como su nombre lo indica, namedtuple es una tupla con nombre. En la tupla estándar, accedemos a los elementos utilizando el índice, mientras que namedtuple permite al usuario definir el nombre de los elementos. Esto es muy útil, especialmente al procesar archivos csv (valores separados por comas) y trabajar con conjuntos de datos complejos y grandes, donde el código se vuelve desordenado con el uso de índices (no tan pitónicos).
¿Cómo usarlos?
Leyendo
Escenario interesante en el procesamiento de CSV:
fuente
En Python dentro hay un buen uso del contenedor llamado tupla con nombre, se puede usar para crear una definición de clase y tiene todas las características de la tupla original.
El uso de tuplas con nombre se aplicará directamente a la plantilla de clase predeterminada para generar una clase simple, este método permite una gran cantidad de código para mejorar la legibilidad y también es muy conveniente al definir una clase.
fuente
Otra forma (una nueva forma) de usar tuplas con nombre es usar NamedTuple desde el paquete de escritura: Escriba sugerencias en namedtuple
Usemos el ejemplo de la respuesta principal en esta publicación para ver cómo usarlo.
(1) Antes de usar la tupla nombrada, el código es así:
(2) Ahora usamos la tupla nombrada
herede la clase NamedTuple y defina el nombre de la variable en la nueva clase. prueba es el nombre de la clase.
crear instancias de la clase y asignarles valores
usar las variables de las instancias para calcular
fuente
Prueba esto:
Básicamente,
namedtuples
son tipos de objetos livianos y fáciles de crear. Convierten las tuplas en contenedores convenientes para tareas simples. Connamedtuples
, no tiene que usar índices enteros para acceder a los miembros de una tupla.Ejemplos:
Código 1:
Código 2:
fuente
Todos los demás ya lo han respondido, pero creo que todavía tengo algo más que agregar.
Namedtuple podría considerarse intuitivamente como un atajo para definir una clase.
Vea una forma engorrosa y convencional de definir a
class
.Como para
namedtuple
fuente
red_duck[0]
olen(red_duck)
ofor x in red_duck: print(x)
. Además, las tuplas con nombre son inmutables, por lo que estas operaciones fallarán:red_duck[0] = 2
,red_duck.foo = 'bar'
. Como son inmutables, las tuplas con nombre se pueden usar comodict
claves.