Python教程-Python中的命名元组
在Python中,有一种“特殊”的元组称为“命名元组”。Python初学者经常对它感到困惑,特别是何时以及为什么我们必须使用它。
因为命名元组是元组,它可以执行所有元组可以执行的功能。然而,它不仅仅是一个简单的Python元组。在其他计算机语言中,就像在C++中一样,它更类似于一个“类”。它是根据我们的规格构建的,具有指定字段和定义长度的元组子类型。本教程将解释Python命名元组,展示如何使用它们,以及何时以及为什么我们必须使用它们。
什么是Python元组?
在继续之前,我们认为应该回顾一下Python中的元组。
Python中的元组是一个可以存储多个值的容器。考虑以下情况。
代码
numbers = (34, 32, 56, 24, 75, 24)
正如我们所看到的,我们使用括号来定义它。通过索引来访问元素。 (请记住,Python中的索引从零开始。)
代码
numbers[1]
输出:
32
Python元组通过其元素不可变的事实而与普通元组分开。
Python命名元组语法
首先,我们必须从Python内置模块collections中导入NamedTuple,如下所示:
from collections import namedtuple
以下是构建命名元组的基本语法:
namedtuple(Name,[Names of Values])
Name是我们想要给命名元组的标题的参数,以及
[Values的名称]是包含不同值或属性名称的名称列表的占位符。
Python命名元组示例
首先,如前所述,要导入NamedTuple。
from collections import namedtuple
现在,我们可以使用前面部分的语法来创建一个命名元组:
Student = namedtuple("Student",["Name","Class","Age","Subject","Marks"])
在这个例子中,
我们选择称为Student的NamedTuple,并在列表中提到了值的名称,“Name”,“Class”,“Age”,“Subject”和“Marks”。我们已经创建了我们的第一个命名元组 - Student。
现在,我们可以使用Student来创建一个具有所需规格的Student1:
Studnet1 = Student("Itika", 11, 15, "English", 79)
只需要在我们的[Values的名称]中的字段中输入具体的值或内容即可。
要输入新的学生信息,比如Student2,只需将其值复制并粘贴到新变量的字段中。
Studnet2 = Student("Arshia", 12, 17, "Maths", 93)
我们将看到我们可以使用Student作为蓝图来随需要记录新的学生,而无需每次都调用字段的标签。
如何使用点符号获取命名元组的值
我们可以使用点方法来获取命名元组实例Student1和Student2的值。以下是语法:
<name of object>.<name of field>
以下代码示例演示了这一点:
代码
print (Student1.Age)
print (Student1.Class)
print (Student1.Subject)
print (Student1.Marks)
print (Student1.Name)
输出:
15
11
"English"
79
"Itika"
同样,我们可以使用Student2.Age,Student2.Class等来检索与NamedTuple Student2相关的变量。
命名元组的访问方法
我们可以使用索引、关键字和getattr()函数从命名元组中检索值。命名元组的字段值是严格有序的。因此,我们可以使用索引来查找它们。
NamedTuple将字段名称转换为属性。因此,可以使用getattr()从该字段中检索数据。
代码
import collections
#create employee NamedTuple
Participant = collections.namedtuple('Participant', ['Name', 'Age', 'Country'])
#Adding two participants
p1 = Participant('Itika', '21', 'India')
p2 = Participant('Arshia', '19', 'Australia')
#Accessing the items using index
print( 'The name and country of the first participant are: ' + p1[0] + ' and ' + p1[2])
#Accessing the items using name of the field
print( 'The name and country of the second participant are: ' + p2.Name + ' and ' + p2.Country)
#Accessing the items using the method: getattr()
print( 'The Age of participant 1 and 2 are: ' + getattr(p1, 'Age') + ' and ' + getattr(p2, 'Age'))
输出:
The name and country of the first participant are: Itika and India
The name and country of the second participant are: Arshia and Australia
The Age of participant 1 and 2 are: 21 and 19
命名元组的转换方法
可以使用几种技术将不同的集合转换为命名元组。我们还可以使用_make()函数将列表、元组或其他可迭代对象转换为命名元组实例。
还可以将字典数据类型对象转换为命名元组集合。这需要使用**操作符进行转换。
作为OrderedDict数据类型项,NamedTuple可以使用其键生成项。我们可以调用_asdict()函数将其转换为OrderedDict。
代码
import collections
#create employee NamedTuple
Participant = collections.namedtuple('Participant', ['Name', 'Age', 'Country'])
#List to Participants
list_ = ['Itika', '21', 'India']
p1 = Participant._make(list_)
print(p1)
#Dict to convert Employee
dict_ = {'Name':'Arshia', 'Age' : '19', 'Country' : 'Australia'}
p2 = Participant(**dict_)
print(p2)
#Displaying the namedtuple as dictionary
participant_dict = p1._asdict()
print(participant_dict)
输出:
Participant(Name='Itika', Age='21', Country='India')
Participant(Name='Arshia', Age='19', Country='Australia')
{'Name': 'Itika', 'Age': '21', 'Country': 'India'}
命名元组的更多操作
还有其他方法,例如_fields()和_replace。我们可以通过调用_fields()函数确定命名元组具有哪些字段。_replace()函数用于将一个值替换为另一个值。
代码
import collections
#create employee NamedTuple
Participant = collections.namedtuple('Participant', ['Name', 'Age', 'Country'])
#List to Participants
p1 = Participant('Itika', '21', 'India')
print(p1)
print('The fields of Participant: ' + str(p1._fields))
#updating the country of participant p1
p1 = p1._replace(Country = 'Germany')
print(p1)
输出:
Participant(Name='Itika', Age='21', Country='India')
The fields of Participant: ('Name', 'Age', 'Country')
Participant(Name='Itika', Age='21', Country='Germany')
Python的命名元组是如何工作的?
让我们看看在Python中的命名元组可以实现哪些额外功能。
1. Python中的命名元组是不可变的。
与其普通版本一样,Python中的命名元组是不可修改的。我们无法修改它的特性。
我们将尝试修改名为'Student'的元组的一个特性以演示这一点。
代码
from collections import namedtuple
Student = namedtuple("Student",["Name","Class","Age","Subject","Marks"])
Student1 = Student("Arshia", 12, 17, "Maths", 93)
Student1.Class = 11
输出:
AttributeError Traceback (most recent call last)
Input In [41], in ()
2 Student = namedtuple("Student",["Name","Class","Age","Subject","Marks"])
3 Student1 = Student("Arshia", 12, 17, "Maths", 93)
----> 4 Student1.Class = 11
AttributeError: can't set attribute
如您所见,它引发了AttributeError。因此,我们可以推断出命名元组是不可变的。
2. 从Python命名元组创建Python字典
在Python中,命名元组类似于字典,我们可以通过以下方式将其转换为字典:
代码
from collections import namedtuple
Student = namedtuple("Student",["Name","Class","Age","Subject","Marks"])
Student1 = Student("Arshia", 12, 17, "Maths", 93)
print ( Student1._asdict() )
输出:
{'Name': 'Arshia', 'Class': 12, 'Age': 17, 'Subject': 'Maths', 'Marks': 93}
我们使用.asdict()方法来执行此操作。这也生成了一个Python OrderedDict。
3. 具有默认值的命名元组
与普通类中的属性一样,可以为命名元组类配置默认参数。因为具有默认值的字段应出现在没有默认值的每个字段之后,所以默认值分配给最右边的字段。
让我们用只有1个默认条目重新定义Student类。
代码
from collections import namedtuple
Student = namedtuple("Student", ["Name","Class","Age","Subject","Marks"], defaults = [100])
Student1 = Student("Arshia", 12, 17, "Maths")
print ( Student1 )
输出:
Student(Name='Arshia', Class=12, Age=17, Subject='Maths', Marks=100)
如果只有一个值来创建NamedTuple,那么将应用默认值100,这是我们声明中最右边的字段。
如果我们明确指定字段为Age,那么Age的默认值会被应用吗?
代码
from collections import namedtuple
Student = namedtuple("Student", ["Name","Class","Age","Subject","Marks"], defaults = [100])
Student1 = Student("Arshia", 12, 17, "Maths")
Student1 = Student(Age = 18)
print ( Student1 )
输出:
TypeError: Student.__new__() missing 3 required positional arguments: 'Name', 'Class', and 'Subject'
答案是否定的。在命名元组中,字段的顺序非常严格。即使我们明确声明了任何内容,也必须将默认值放在最右边,以避免歧义和潜在的困难。
Python命名元组的好处
当然,如果没有看到任何好处,没有人会使用NamedTuple。因此,这是我们得到的:
1.与普通元组不同,Python中的NamedTuple可以通过其标题检索变量。
代码
from collections import namedtuple
Student = namedtuple("Student", ["Name","Class","Age","Subject","Marks"], defaults = [100])
Student1 = Student("Arshia", 12, 17, "Maths")
print ( Student1.Age )
输出:
17
2.由于它不包含每个实例的字典,所以Python NamedTuple在内存中是高效的,就像普通元组一样。由于这个原因,它比字典更快。
结论
在本教程中,我们学习了NamedTuples如何允许我们结合元组和字典的优点,如何创建NamedTuples以及如何在Python中使用它们,以及它们的工作原理
如果读者熟悉Python的面向对象编程,他们将会发现这与Python类的工作方式相同。一个类及其属性充当了创建许多对象或实例的蓝图,每个对象都有自己的一组属性值。
然而,通常情况下,为了增加代码的清晰度,定义一个类并提供必要的特性通常是多余的,构建NamedTuples要快得多。