Вопрос

Чтение изменения в Python 3.1, я нашел кое-что...непредвиденный:

Кортеж sys.version_info теперь является именованный кортеж:

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

Итак, мои вопросы:

  • Что называют кортежами?
  • Как их использовать?
  • Почему/когда мне следует использовать именованные кортежи вместо обычных кортежей?
  • Почему/когда мне следует использовать обычные кортежи вместо именованных кортежей?
  • Существует ли какой-либо «именованный список» (изменяемая версия именованного кортежа)?
Это было полезно?

Решение

Названные кортежи в основном просты для создания, легкие типы объектов. Названные экземпляры кортежа могут быть направлены на с использованием объектной переменной Derefercrencing или стандартного синтаксиса кортежей. Их можно использовать аналогично struct или другие общие типы записей, за исключением того, что они неизбежны. Они были добавлены в Python 2.6 и Python 3.0, хотя есть Рецепт реализации в Python 2.4.

Например, обычно представляют собой точку как кортеж (x, y). Анкет Это приводит к коду, как следующее:

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)

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

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)

Тем не менее, названные кортежи по -прежнему совместимы с нормальными кортежами, поэтому все еще будет работать следующее:

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

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

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

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

Однако, как и в случае кортежей, атрибуты в названных кортежах неизменны:

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

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

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

Однако я не знаю ни о какой форме «названного списка», которая позволяет добавлять новые поля. Вы можете просто захотеть использовать словарь в этой ситуации. Названные кортежи могут быть преобразованы в словаря с использованием pt1._asdict() который возвращается {'x': 1.0, 'y': 5.0} и может работать со всеми обычными функциями словаря.

Как уже отмечалось, вы должны Проверьте документацию Для получения дополнительной информации, из которой были построены эти примеры.

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

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

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)

Что называются кортежи?

Названный кортеж - это кортеж.

Он делает все, что может.

Но это больше, чем просто кортеж.

Это конкретный подкласс кортежей, который программно создается для вашей спецификации, с названными полями и фиксированной длиной.

Это, например, создает подкласс кортежей, и, помимо того, что он имеет фиксированную длину (в данном случае, три), его можно использовать везде, где используется кортеж без лома. Это известно как замена Лискова:

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

Это создает это:

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

Мы можем осмотреть его и использовать его атрибуты:

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

Более глубокое объяснение

Чтобы понять названные кортежи, вам сначала нужно знать, что такое кортеж. Круп, по сути, является неизменным (не может быть изменен на месте в памяти).

Вот как вы можете использовать обычный кортеж:

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

Вы можете расширить кортеж с итерационным распаковкой:

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

Названные кортежи - это кортежи, которые позволяют получить доступ к их элементам по имени, а не просто индекс!

Вы делаете название как это:

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

Вы также можете использовать одну строку с именами, разделенными пространствами, немного более читаемое использование API:

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

Как их использовать?

Вы можете сделать все, что могут сделать коечки (см. Выше), а также сделать следующее:

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

Комментатор спросил:

В большом сценарии или программе, где обычно определять именованную кортеж?

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

Рабочий пример на уровне глобального модуля:

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

И это демонстрирует неспособность поиска определения:

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

Почему/когда я должен использовать названные кортежи вместо нормальных кортежей?

Используйте их, когда он улучшает ваш код, чтобы получить семантику элементов кортежа в вашем коде. Вы можете использовать их вместо объекта, если бы вы в противном случае использовали объект с неизменными атрибутами данных и без функциональности. Вы также можете подкласс их, чтобы добавить функциональность, например,:

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)

Почему/когда мне следует использовать нормальные кортежи вместо названных кортежей?

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

Нет дополнительной памяти, используемой названными кортежами против кортежей.

Есть ли какой -либо «названный список» (измененная версия названного корпуса)?

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

Теперь расширенный и, возможно, даже заменимый Лискова, пример первого:

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

И использовать, просто подкласс и определить __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

Названные турниры - отличная функция, они являются идеальным контейнером для данных. Когда вам нужно «хранить» данные, вы бы использовали кортежи или словари, например:

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

или же:

user = ("John", 20)

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

Названные тела являются идеальным компромиссом для двух подходов, которые имеют отличную читабельность, легкую вес и неизменность (плюс они полиморфны!).

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

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

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

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

natingtuple

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

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"

Без названия каждого элемента в кортеже, он прочитал бы так:

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"

Гораздо сложнее понять, что происходит в первом примере. С именованным, каждое поле имеет имя. И вы получаете доступ к нему по имени, а не на позиции или индексе. Вместо p[1], мы можем назвать это P.Saturation. Это легче понять. И это выглядит чище.

Создание экземпляра названного турнира проще, чем создать словарь.

# 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

Когда вы можете использовать nameTuple

  1. Как только что говорилось, названная ставка делает понимание кортежей намного проще. Поэтому, если вам нужно ссылаться на элементы в кортеже, то создание их как названные просто имеет смысл.
  2. Помимо того, что он более легкий, чем словарь, Nalittuple также сохраняет заказ в отличие от словаря.
  3. Как и в примере выше, проще создавать экземпляр названной именной, чем словарь. И ссылка на предмет в названном корпусе выглядит чище, чем словарь. p.hue скорее, чемp['hue'].

Синтаксис

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • NALICTUPLE находится в библиотеке коллекций.
  • Typename: это имя нового подкласса Tuple.
  • Field_Names: последовательность имен для каждого поля. Это может быть последовательность, как в списке ['x', 'y', 'z'] или строка x y z (Без запятых, просто пробел) или x, y, z.
  • Переименование: если переименовать True, недействительные имена FieldNemals автоматически заменяются позиционными именами. Например, ['abc', 'def', 'ghi','abc'] преобразуется в ['abc', '_1', 'ghi', '_3'], Устранение ключевого слова 'def' (Поскольку это зарезервированное слово для определения функций) и дубликат FieldName 'abc'.
  • ПРОГлад: если словеса True, Определение класса напечатано непосредственно перед построением.

Вы все еще можете получить доступ к названию по своей позиции, если вы выберете. p[1] == p.saturation. Анкет Это все еще распаковывается, как обычный кортеж.

Методы

Все Регулярные методы кортежа поддерживаются. Пример: min (), max (), len (), in, не в, incatenation (+), индекс, срез и т. Д., И есть несколько дополнительных для названной именной. Примечание: все это начинается с подчеркивания. _replace, _make, _asdict.

_replaceВозвращает новый экземпляр именованного корпуса, заменяющего указанные поля новыми значениями.

Синтаксис

somenamedtuple._replace(kwargs)

Пример

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

Уведомление: Имена поля не в кавычках; Это ключевые слова здесь.Запомнить: ПУЛЕЙ НЕПРАВИЛЬНО - даже если они названы и имеют _replace метод А _replace производит new пример; Он не изменяет исходный или заменит старое значение. Конечно, вы можете сохранить новый результат с переменной. p = p._replace(hue=169)

_make

Делает новый экземпляр из существующей последовательности или итерапильно.

Синтаксис

somenamedtuple._make(iterable)

Пример

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

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

_asdict

Возвращает новый Заказан которые отображают поля имена по их соответствующим значениям.

Синтаксис

somenamedtuple._asdict()

Пример

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

Ссылка: https://www.reddit.com/r/python/comments/38ee9d/intro_to_namedtuple/

Существует также названный список, который похож на названный кортеж, но изменяетсяhttps://pypi.python.org/pypi/namedlist

Что называется?

Как следует из названия, NALITTUPLE - это кортеж с именем. В Standard Cutle мы получаем доступ к элементам, используя индекс, тогда как NameTuple позволяет пользователю определять имя для элементов. Это очень удобно, особенно обработка файлов CSV (разделенного запятой) и работа со сложным и большим набором данных, где код становится грязным с использованием индексов (не такого Pythonic).

Как их использовать?

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

Чтение

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

Интересный сценарий в обработке CSV:

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)

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

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

Другой способ (новый способ) использовать с именем Tuple, использует nameTuple из пакета Typing: Тип подсказки в nameltuple

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

(1) Перед использованием именованного корпуса код такой:

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) Теперь мы используем названный кортеж

from typing import NamedTuple, Number

Унаследовать класс именования имены имени и определите имя переменной в новом классе. Тест - это название класса.

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

Создайте экземпляры из класса и присвойте им значения

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

Используйте переменные из экземпляров для расчета

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

Попробуй это:

collections.namedtuple()

В принципе, namedtuples легко создавать, легкие типы объектов. Они превращают кортежи в удобные контейнеры для простых задач. С namedtuples, вам не нужно использовать целочисленные индексы для доступа к членам кортежа.

Примеры:

Код 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

Код 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

Все остальные уже ответили на это, но я думаю, что мне еще есть что добавить.

NALICTUPLE может быть интуитивно считать ярлыком для определения класса.

Увидеть громоздкий и обычный способ определения 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'

Что касается 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'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top