python当中的结构体及其排序

  • Post author:
  • Post category:python

一.使用collections模块中的namedtuple类型

1.namedtuple表示结构体
python当中可以采用namedtuple,即命名元组来表示结构体。(namedtuple实际上是一个可以用来创建具有命名字段的轻量级对象的工厂函数)
下面举一个简单的例子:

from collections import namedtuple

# 创建一个表示点的结构体
Point = namedtuple('Point', ['x', 'y'])

# 创建一个Point对象p
p = Point(1, 2)

# 访问对象的属性
print(p.x) # 输出: 1
print(p.y) # 输出: 2

在上面的例子中,我们使用namedtuple函数创建了一个名为Point的结构体,它有两个属性x和y,分别表示点的横坐标和纵坐标。然后我们创建了一个Point对象p,并访问了它的属性。

使用namedtuple可以让代码更加清晰和易读,因为它可以像普通对象一样访问属性,同时又具有元组的不变性和轻量级的性能。

2.结构体排序:
法一:利用operator模块中的attrgetter函数
(1)首先导入namedtuple和operator模块

from collections import namedtuple
import operator

(2)创建结构体,定义属性

Person = namedtuple('Person', ['name', 'age', 'height'])#创建一个名为Person的命名元组,属性为name age height等等

(3)创建包含多个结构体对象的列表

people = [
    Person('Alice', 25, 165),
    Person('Bob', 30, 175),
    Person('Charlie', 20, 180)
]

(4)使用operator模块中的attrgetter函数来指定按照哪个属性进行排序。(默认为升序,可以使用reverse=True来进行降序排列)
默认升序:

sorted_people = sorted(people, key=operator.attrgetter('age'))#指定按照age属性进行升序排序

降序:

sorted_people = sorted(people, key=operator.attrgetter('age'), reverse=True)#指定reverse为True,即进行降序排序

法二:采用匿名函数
先来介绍一下匿名函数:
在python当中,可以使用lambda表达式来创建匿名函数,lambda表达式可以在需要函数对象的任何地方进行使用,例如,可以将它们用作参数传递给其他函数,或在列表解析、map()、filter()等函数中使用。
下来是一个简单的例子:

# 创建一个匿名函数,用于计算两个数的和
sum = lambda x, y: x + y

# 调用匿名函数
result = sum(10, 20)
print(result)  # 输出30

在上面的例子中,我们使用lambda表达式创建了一个计算两个数之和的匿名函数,并将其赋值给变量sum。然后,我们调用了这个匿名函数,并传入了两个参数10和20,得到了30这个结果。

您还可以将lambda表达式用作其他函数的参数。例如,以下是使用lambda表达式和map()函数将一个列表中的所有元素加1的示例:

# 创建一个列表
numbers = [1, 2, 3, 4, 5]

# 使用lambda表达式和map()函数将列表中的所有元素加1
new_numbers = list(map(lambda x: x + 1, numbers))

# 输出结果
print(new_numbers)  # 输出[2, 3, 4, 5, 6]

在上面的示例中,我们首先创建了一个列表numbers,然后使用map()函数和lambda表达式将列表中的所有元素加1。 lambda表达式lambda x: x + 1接受一个参数x,并返回x + 1的结果。 map()函数将lambda表达式应用于列表中的每个元素,并返回一个新的迭代器。最后,我们使用list()函数将迭代器转换回列表,并将结果赋值给new_numbers变量
下面再来介绍一下如何采用匿名函数进行结构体排序:

sorted_people=sorted(people,key=lambda x:x.age)

上述代码中,我们使用内置函数sorted()来对列表当中所有的元素进行排序,并且设置一个匿名函数作为函数key的参数,该匿名函数用于接收一个参数x,返回x的age属性值,key函数会在列表中的每个元素进行调用,即返回列表中每个Person对象的age属性值,告诉sorted函数按照age值从小到大进行升序排序。
也可以改变匿名函数的返回值来调整排序顺序:

sorted_people=sorted(people,key=lambda x:-x.age)

上述代码就是按照age值从大到小进行降序排序。
原题:
题目连接
代码示例:

from collections import namedtuple
fact=namedtuple('fact',['x','s'])
lst=[]
n=int(input())
for i in range(n):
    s1=input()
    x1,x2=map(str,s1.split())
    ans=fact(x=int(x1),s=x2)
    lst.append(ans)
sorted_lst=sorted(lst,key=lambda p:-p.x)
#sorted_lst=sorted(lst,key=operator.attrgetter('x'),reverse=True)
for i in sorted_lst:
    print(i.s)

二. 使用元组模拟

在 Python 中,元组可以被用作一种简单的数据结构,类似于 C 语言中的结构体。元组是一个不可变的序列,可以包含多个元素,每个元素可以是不同类型的数据。
创建一个元组来模拟结构体,元组可以通过逗号分隔来表示不同的属性值,然后通过索引来访问这些属性值:

struct = ('John', 30, 'Male')
``
在这个例子中,struct 变量包含了一个名为 John、年龄为 30 年、性别为男性的人的数据。
我们可以使用索引来访问元组中的元素:
```python
name = struct[0]
age = struct[1]
gender = struct[2]

可以像这样将元组作为参数传递给函数,或者将元组的元素解包到变量中:

def print_struct(struct):
    name, age, gender = struct
    print("Name:", name)
    print("Age:", age)
    print("Gender:", gender)
print_struct(struct)
函数输出:
Name: John
Age: 30
Gender: Male

题目同上:
代码实例:

lst=[]
n=int(input())
for i in range(n):
    s1=input()
    x1,x2=map(str,s1.split())
    ans=(int(x1),x2)
    lst.append(ans)
sorted_lst=sorted(lst,key=lambda x: -x[0])
for i in sorted_lst:
    print(i[1])

总结
在Python中,使用元组模拟结构体和使用namedtuple表示结构体都有各自的优点和缺点,具体使用哪个取决于具体的需求和场景。

1.使用元组模拟结构体的主要优点是简单和轻量级,因为元组是Python内置类型,而且不需要定义新的数据类型。同时,元组也是不可变的,这可以确保数据的不可变性,避免了无意间修改数据的风险。但是,元组没有类对象那样的方法和属性,也不能继承其他类或结构体,这限制了它的灵活性和扩展性。

2.使用namedtuple表示结构体可以更好地组织数据,并且支持方法和属性,这使得代码更加清晰和易于维护。另外,namedtuple还可以继承其他类或结构体,这使得它更加灵活和可扩展。但是,namedtuple相对于元组而言稍微复杂一些,需要引入新的数据类型,并且有时候可能会占用更多的内存空间。

因此,根据具体需求和场景,可以根据这些优缺点来选择使用元组或namedtuple表示结构体。一般来说,在需要表示简单和轻量级数据结构时,可以使用元组模拟结构体;而在需要更复杂的数据结构或者需要支持方法和属性时,可以使用namedtuple表示结构体


版权声明:本文为m0_71434369原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。