我正在开发一个使用合并排序对数据进行排序的程序。我为“Person”类实现了函数,使其具有可比较性、可排序性、可下标性、可迭代性和可转换性(浮点型、整数型和字符串型)。我想定义一切,一旦没有代码重复 - 编写干代码。我是否实现了某些功能(例如魔术方法)两次?
有没有具体位置可以更短一些?并同时保留所有功能?如果是这样,建议更改特定行。
import numpy as np
import load_names
import enum
from merge_sort import mergesort
NAMES = load_names.load_names() # Variables in the global namespace
class Person():
def __init__(self, name, age, height, weight):
self._name = name
self._age = age
self._height = height
self._weight = weight
#def __len__(self):
#return len(self.data)
def __repr__(self):
return f"{self._name}, {self._age} years, {self._height} cm, {self._weight} kg\n"
def __eq__(self, other):
return (self._age, self._height, self._weight) == (other._age, other._height, other._weight)
def __lt__(self, other):
return (self._age, self._height, self._weight) < (other._age, other._height, other._weight)
def __le__(self, other):
return (self._age, self._height, self._weight) <= (other._age, other._height, other._weight)
def __gt__(self, other):
return (self._age, self._height, self._weight) > (other._age, other._height, other._weight)
def __ge__(self, other):
return (self._age, self._height, self._weight) >= (other._age, other._height, other._weight)
def __str__(self):
return f"{self._name}, {self._age} years, {self._height} cm, {self._weight} kg"
def __getitem__(self, index):
if index == 0:
return self._name
elif index == 1:
return self._age
elif index == 2:
return self._weight
elif index == 3:
return self._height
else:
raise IndexError("Index out of range")
def __int__(self):
return int(self._age)
def __float__(self):
return float(self._age)
def to_tuple(self):
return (self._name, self._age, self._weight, self._height)
def to_list(self):
return [self._name, self._age, self._weight, self._height]
def get_name(self):
return self._name
def get_age(self):
return self._age
def get_height(self):
return self._height
def get_weight(self):
return self._weight
def create_persons_list(n=10, sort_key='height'):
person_objects = [(Person(np.random.choice(NAMES), np.random.randint(18, 101), np.random.randint(150, 201), np.random.randint(45, 101))) for _ in range(n)]
#print("po: ",person_objects[0])
x=Person()
if sort_key == 'name':
return mergesort(person_objects, key=lambda x: x.get_name())
elif sort_key == 'age':
return mergesort(person_objects, key=lambda x: x.get_age())
elif sort_key == 'height':
return mergesort(person_objects, key=lambda x: x.get_height())
elif sort_key == 'weight':
return mergesort(person_objects, key=lambda x: x.get_weight())
else:
return mergesort(person_objects)
# Example usage:
sorted_persons_by_name = create_persons_list(sort_key='name')
sorted_persons_by_age = create_persons_list(sort_key='age')
sorted_persons_by_height = create_persons_list(sort_key='height')
sorted_persons_by_weight = create_persons_list(sort_key='weight')
print("Sorted by height (default): \n")
print(sorted_persons_by_height)
print("Sorted by name: \n")
print(sorted_persons_by_name)
print("Sorted by age: \n")
print(sorted_persons_by_age)
print("Sorted by weight: \n")
print(sorted_persons_by_weight)
print("No key arg: ", create_persons_list())
#print(create_persons_list())
是的,你可以让代码更简洁。
您可以使用字典将索引映射到属性,而不是“getitem”方法中的一系列“if-elif”语句。
def getitem(自我,索引): 属性 = {0: self._name, 1: self._age, 2: self._weight, 3: self._height} 如果属性中有索引: 返回属性[索引] 引发 IndexError("索引超出范围")
您可以使用字典将排序键映射到相应的 lambda 函数,而不是为每个排序键设置单独的条件。
def create_persons_list(n=10, sort_key='height'): key_mapping = {'name': 'get_name', 'age': 'get_age', 'height': 'get_height', '体重':'get_weight'} key_func = lambda x: getattr(x, key_mapping.get(sort_key, 'to_tuple'))() 返回 mergesort([Person(np.random.choice(NAMES), np.random.randint(18, 101), np.random.randint(150, 201), np.random.randint(45, 101)) for _ in range(n)], key=key_func)