Question

Lire les en Python 3.1 , j'ai trouvé quelque chose ... inattendu:

Le tuple sys.version_info est maintenant un nom tuple :

Je ne ai entendu parler tuples nommés avant, et je pensais que les éléments pourraient être soit indexés par des nombres (comme dans tuples et listes) ou par touches (comme dans dicts). Je ne pensais pas qu'ils pourraient être indexés dans les deux sens.

Ainsi, mes questions sont:

  • Qu'est-ce que sont nommés tuples?
  • Comment les utiliser?
  • Pourquoi / quand dois-je utiliser nommé tuples au lieu de tuples normaux?
  • Pourquoi / quand dois-je utiliser tuples normale au lieu de tuples nommé?
  • Y at-il sorte de "liste nommée" (une version mutable du tuple nom)?
Était-ce utile?

La solution

sont essentiellement nommés tuples faciles à créer, types d'objets légers. Nommées instances de tuple peuvent être référencés à l'aide objet comme déréférencement variable ou la syntaxe standard de tuple. Ils peuvent être utilisés de façon similaire à struct ou d'autres types d'enregistrement commun, sauf qu'ils sont immuables. Ils ont été ajoutés en Python 2.6 et Python 3.0, bien qu'il y ait une recette pour la mise en œuvre en Python 2.4 .

Par exemple, il est courant de représenter un point comme (x, y) tuple. Cela conduit à un code comme suit:

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)

L'utilisation d'un tuple nommé il devient plus lisible:

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)

Cependant, tuples nommés sont toujours en arrière compatible avec tuples normaux, donc ce qui suit va encore du travail:

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

Ainsi, vous devez utiliser au lieu nommé tuples de tuples où vous pensez que la notation objet va rendre votre code plus pythonique et plus facilement lisible . Personnellement, j'ai commencé à les utiliser pour représenter les types de valeurs très simples, en particulier en les passant en tant que paramètres aux fonctions. Il rend les fonctions plus lisibles, sans voir le contexte de l'emballage tuple.

En outre, vous pouvez également remplacer ordinaires immuable classes qui ont pas de fonctions , seuls les champs avec eux. Vous pouvez même utiliser vos types de tuple nommés classes de base:

class Point(namedtuple('Point', 'x y')):
    [...]

Cependant, comme tuples, les attributs de tuples nommés sont immuables:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

Si vous voulez être en mesure le changement des valeurs, vous avez besoin d'un autre type. Il y a une recette pratique pour mutable recordtypes qui vous permettent de définir de nouvelles valeurs aux attributs.

>>> 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

Je ne suis pas au courant d'aucune forme de « liste nommée » qui vous permet d'ajouter de nouveaux champs, cependant. Vous pouvez juste utiliser un dictionnaire dans cette situation. Nommés tuples peuvent être convertis en utilisant des dictionnaires pt1._asdict() qui retourne {'x': 1.0, 'y': 5.0} et peut être utilisé sur toutes les fonctions habituelles du dictionnaire.

Comme indiqué précédemment, vous devriez consultez la documentation pour plus d'informations à partir de laquelle ces exemples ont été construits.

Autres conseils

namedtuple est un Fonction usine pour faire un classe tuple. Avec cette classe, nous pouvons créer tuples qui sont appelables par nom aussi.

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

Qu'est-ce que sont nommés tuples?

Un tuple nommé est un tuple.

Il fait tout une boîte tuple.

Mais il est plus que juste un tuple.

Il est une sous-classe spécifique d'un tuple qui est créé par programme à votre cahier des charges, avec des champs nommés et une longueur fixe.

, par exemple, crée une sous-classe de tuple, et en plus d'être de longueur fixe (dans ce cas, trois), il peut être utilisé partout un tuple est utilisé sans casser. Ceci est connu comme substituabilité Liskov:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

instancie:

>>> ant = ANamedTuple(1, 'bar', [])

Nous pouvons inspecter et utiliser ses attributs:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

explication Deeper

Pour comprendre tuples nommé, vous devez d'abord savoir ce qu'est un tuple est. Un tuple est essentiellement un immuable (ne peut pas être changé en place en mémoire) liste.

Voici comment vous pouvez utiliser un tuple régulier:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

Vous pouvez développer un tuple avec décompactage itérables:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

sont nommés tuples tuples qui permettent à leurs éléments accessibles par nom au lieu de l'index juste!

Vous faites un namedtuple comme ceci:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

Vous pouvez également utiliser une seule chaîne avec les noms séparés par des espaces, une utilisation un peu plus lisible de l'API:

>>> Student = namedtuple('Student', 'first last grade')

Comment les utiliser?

Vous pouvez faire tuples tout peut faire (voir ci-dessus), ainsi que faire ce qui suit:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

Un intervenant a demandé:

Dans un grand script ou un programme, où définit-on habituellement un tuple nommé?

Les types que vous créez avec namedtuple sont les classes que vous pouvez créer avec essentiellement un raccourci facile. Les traiter comme des cours. les définir au niveau du module, de sorte que cornichon et d'autres utilisateurs peuvent les trouver.

L'exemple de travail, au niveau du module global:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

Et cela démontre l'échec de rechercher la définition:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

Pourquoi / quand dois-je utiliser nommé tuples au lieu de tuples normaux?

Utilisez-les quand il améliore votre code pour avoir la sémantique des éléments de tuple exprimés dans votre code. Vous pouvez les utiliser au lieu d'un objet si vous sinon utiliser un objet avec des attributs de données immuables et aucune fonctionnalité. Vous pouvez également les sous-classe pour ajouter des fonctionnalités, par exemple :

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

Pourquoi / quand dois-je utiliser tuples normale au lieu de tuples nommé?

Il serait sans doute une régression à passer de l'aide tuples nommé à tuples. Les centres de décision de conception initiaux à savoir si le coût du code supplémentaire impliqué vaut la meilleure lisibilité lorsque le tuple est utilisé.

Il n'y a pas de mémoire supplémentaire utilisé par tuples nommé par rapport tuples.

Y at-il sorte de "liste nommée" (une version mutable du tuple nom)?

Vous cherchez soit un objet rainuré qui implémente toutes les fonctionnalités d'une liste statique de taille ou une liste qui fonctionne comme sous-classé un tuple nom (et qui en quelque sorte bloque la liste de changer la taille.)

A maintenant étendu, et peut-être même substituable Liskov, exemple du premier:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

Et à l'utilisation, juste sous-classe et de définir __slots__:

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

namedtuples sont une grande fonctionnalité, ils sont parfaits pour les données contenant. Lorsque vous avez des données que vous utilisez, comme tuples ou dictionnaires « magasin »:

user = dict(name="John", age=20)

ou

user = ("John", 20)

L'approche dictionnaire est écrasante, puisque dict sont mutable et plus lent que tuples. D'autre part, les tuples sont immuables et léger, mais manquent de lisibilité pour un grand nombre d'entrées dans les champs de données.

namedtuples sont le parfait compromis pour les deux approches, ont une grande lisibilité, et immuabilité légèreté (plus ils sont polymorphes!).

tuples nommés permettent une compatibilité descendante avec le code qui vérifie la version comme ceci

>>> sys.version_info[0:2]
(3, 1)

tout en permettant le code de l'avenir d'être plus explicite en utilisant cette syntaxe

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

namedtuple

est l'un des moyens les plus faciles à nettoyer votre code et le rendre plus lisible. Il auto-documents ce qui se passe dans le tuple. les instances Namedtuples sont tout aussi efficace que la mémoire tuples réguliers car ils ne disposent pas des dictionnaires par instance, les rendant plus rapides que les dictionnaires.

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

Sans nommer chaque élément du tuple, on lirait comme suit:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

Il est beaucoup plus difficile de comprendre ce qui se passe dans le premier exemple. Avec un namedtuple, chaque champ a un nom. Et vous accédez par nom plutôt que la position ou de l'indice. Au lieu de p[1], nous pouvons l'appeler p.saturation. Il est plus facile à comprendre. Et il semble plus propre.

Création d'une instance de la namedtuple est plus facile que la création d'un dictionnaire.

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

Quand pourriez-vous utiliser namedtuple

  1. Comme vient de le dire, le namedtuple fait comprendre beaucoup tuples Plus facile. Donc, si vous avez besoin de référencer les éléments dans le tuple, puis les créer comme namedtuples tout à fait logique.
  2. En plus d'être plus léger qu'un dictionnaire, namedtuple aussi maintient l'ordre à la différence du dictionnaire.
  3. Comme dans l'exemple ci-dessus, il est plus simple de créer une instance de namedtuple que le dictionnaire. Et faisant référence au point dans le nom tuple semble plus propre qu'un dictionnaire. p.hue plutôt que p['hue'].

La syntaxe

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple est dans la bibliothèque de collections.
  • typename. C'est le nom de la nouvelle sous-classe tuple
  • FIELD_NAMES: une séquence de noms pour chaque champ. Il peut être une séquence comme dans une ['x', 'y', 'z'] liste ou une chaîne x y z (sans virgules, juste des espaces) ou x, y, z.
  • changement de nom: Si renommage est True, fieldnames incorrects sont automatiquement remplacé par des noms de position. Par exemple, ['abc', 'def', 'ghi','abc'] est converti en ['abc', '_1', 'ghi', '_3'], éliminant ainsi le mot-clé 'def' (puisque c'est un mot réservé pour définir des fonctions) et le double nomchamp 'abc'.
  • bavard: Si bavard est True, la définition de classe est imprimée juste avant d'être construit.

Vous pouvez toujours namedtuples d'accès par leur position, si vous le souhaitez. p[1] == p.saturation. Il décompresse encore comme un tuple régulier.

Méthodes

Toutes les méthodes de tuple régulières sont pris en charge. Ex: min (), max (), len (), dans, non, concaténation (+), index, tranche, etc. Et il y a quelques unes supplémentaires pour namedtuple. Remarque: ces commencent tous avec un trait de soulignement. _replace, _make, _asdict.

_replace Renvoie une nouvelle instance de tuple nommé remplaçant les champs indiqués avec de nouvelles valeurs.

La syntaxe

somenamedtuple._replace(kwargs)

Exemple

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

Avis : Les noms de champs ne sont pas entre guillemets; ils sont des mots clés ici. Rappelez-vous : Tuples sont immuables - même si elles sont namedtuples et ont la méthode _replace. Le _replace produit une instance de new; il ne modifie pas l'original ou de remplacer l'ancienne valeur. Vous pouvez bien sûr sauver le nouveau résultat à la variable. p = p._replace(hue=169)

_make

Donne une nouvelle instance d'une séquence existante ou iterable.

La syntaxe

somenamedtuple._make(iterable)

Exemple

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

Qu'est-ce qui est arrivé avec le dernier? L'élément à l'intérieur de la parenthèse doit être itérable. Ainsi, une liste ou tuple dans les œuvres de parenthèses, mais la séquence de valeurs sans enfermer comme iterable renvoie une erreur.

_asdict

Retourne une nouvelle OrderedDict associant les noms de champ à leur les valeurs correspondantes.

La syntaxe

somenamedtuple._asdict()

Exemple

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

Référence : https: // www. reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

Il y a aussi la liste nommée qui est similaire à tuple nommé mais mutable https://pypi.python.org/pypi/namedlist

Qu'est-ce que namedtuple?

Comme son nom l'indique, namedtuple est un tuple avec le nom. En tuple standard, nous avons accès à des éléments à l'aide de l'indice, alors que namedtuple permet à l'utilisateur de définir le nom des éléments. Ceci est très pratique des fichiers de traitement particulier csv (valeurs séparées par des virgules) et travailler avec ensemble de données complexes et de grande, où le code devient désordonné avec l'utilisation d'indices (pas pythonique).

Comment les utiliser?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

Lecture

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

Scénario intéressant au format CSV Traitement:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

En Python à l'intérieur il y a un bon usage du conteneur appelé un tuple nommé, il peut être utilisé pour créer une définition de classe et a toutes les caractéristiques du tuple d'origine.

En utilisant le nom tuple sera directement appliqué au modèle de classe par défaut pour générer une classe simple, cette méthode permet beaucoup de code pour améliorer la lisibilité et il est également très pratique lors de la définition d'une classe.

Une autre façon (une nouvelle façon) d'utiliser le nom tuple utilise namedtuple du package en tapant: remarques en namedtuple

Soit de l'utilisation de l'exemple de la réponse de haut dans cet article pour voir comment l'utiliser.

(1) Avant d'utiliser le nom tuple, le code est comme ceci:

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)
print(line_length)

(2) Maintenant, nous utilisons le nom tuple

from typing import NamedTuple, Number

hériter de la classe namedtuple et définir le nom de la variable dans la nouvelle classe. test est le nom de la classe.

class test(NamedTuple):
x: Number
y: Number

créer des instances de la classe et attribuer des valeurs à les

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

utilisez les variables des instances à calculer

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

Essayez ceci:

collections.namedtuple()

En gros, namedtuples sont faciles à créer, types d'objets légers. Ils se tournent tuples dans des conteneurs commodes pour des tâches simples. Avec namedtuples, vous ne devez pas utiliser des entiers indices pour accéder à des membres d'un tuple.

Exemples:

Code 1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

Code 2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

Tout le monde a déjà répondu, mais je pense avoir encore quelque chose à ajouter.

namedtuple pourrait être intuitivement considéré comme un raccourci pour définir une classe.

Voir une lourdeur et de manière classique pour définir un class.

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

En ce qui concerne namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top