pt1 = (1.0, 5.0)pt2 = (2.5, 1.5)
from math import sqrtline_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
使用命名元组,它变得更具可读性:
from collections import namedtuplePoint = namedtuple('Point', 'x y')pt1 = Point(1.0, 5.0)pt2 = Point(2.5, 1.5)
from math import sqrtline_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 referencingline_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)# use tuple unpackingx1, y1 = pt1
import collections
#Create a namedtuple class with names "a" "b" "c"Row = collections.namedtuple("Row", ["a", "b", "c"])
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: 1print 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>>>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 readerfrom 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)
from collections import Sequence
class MutableTuple(Sequence):"""Abstract Base Class for objects that work like mutablenamedtuples. 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'sdef __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')>>> studentStudent('Lisa', 'Simpson', 'A')>>> first, last, grade = student>>> first'Lisa'>>> last'Simpson'>>> grade'A'>>> student[0]'Lisa'>>> student[2]'A'>>> len(student)3>>> 'Lisa' in studentTrue>>> 'Bart' in studentFalse>>> student.first = 'Bart'>>> for i in student: print(i)...BartSimpsonA
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"
>>>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 iterableColor(hue=170, saturation=0.1, luminosity=0.6)
>>>Color._make((170, 0.1, 0.6)) #the tuple is an iterableColor(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 _makeTypeError: 'float' object is not callable
Coords = namedtuple('Coords', ['x', 'y'])coord=Coords(10,20) isinstance(coord,tuple) --> True # namedtuple is subclass of tuple
x,y=coord # Unpackingx=coord[0] # by indexfor e in coord:print(e)
现在我们还可以使用我们对类所做的字段名称来访问数据。
coord.x --> 10coord.y --> 20
由于namedtuple是从元组继承的类生成的,我们可以这样写:
class Coord(tuple):....
“coord”是一个元组,因此是不可变的
namedtuple的"rename"关键字arg
字段名称不能以下划线开头
Coords = namedtuple('Coords', ['x', '_y']) # does not work