Python 如何对对象属性进行排序
我有一个大致如下的对象:Python 如何对对象属性进行排序,python,oop,sorting,Python,Oop,Sorting,我有一个大致如下的对象: class Hand(object): def __init__(self, finger_names, finger_lengths, nail_sizes): self.finger_names = finger_names self.finger_lengths = finger_lengths self.nail_sizes = nail_sizes def _sort_by_finger_leng
class Hand(object):
def __init__(self, finger_names, finger_lengths, nail_sizes):
self.finger_names = finger_names
self.finger_lengths = finger_lengths
self.nail_sizes = nail_sizes
def _sort_by_finger_lengths(self):
????
finger\u name
、finger\u length
和nail\u size
都是同样长的列表或空列表(例如,如果此人尚未测量其nail\u size
)。目标是按手指长度对对象的属性进行排序。因此,如果您从一个手对象开始,列表按从左到右的名称(小指、戒指、中指、指针、拇指)排序,那么您将得到一个手对象,其所有属性都按手指长度排序
像这样:
finger_names = [pinky, thumb, pointer, ring, middle]
finger_lengths = [6, 7, 12, 13, 15]
nail_sizes = []
编辑添加:Hand只是一个示例类。真正的代码有很好的理由为每个属性列出列表。任何人都可以告诉你如何做到这一点,但它似乎很脆弱。为什么不做一个
Finger
课程,让自己保持清醒呢
class Finger(object):
PINKY = 0
RING = 1
MIDDLE = 2
INDEX = 3
THUMB = 4
def __init__ (self, type):
self.type = type
self.length = None
self.nail_size = None
def __lt__ (self, other):
return self.length < other.length
f = Finger(Finger.PINKY)
f.length = 6
类手指(对象):
小指=0
环=1
中间=2
指数=3
拇指=4
定义初始化(自我,类型):
self.type=type
self.length=None
self.nail\u size=无
定义(自身、其他):
返回self.length
这两个方向都很容易排序,而且您不必担心哪些手指报告了长度,哪些没有。一个简单的方法是:
>>> finger_names, finger_lengths
(('pointer', 'ring', 'pinky', 'middle', 'thumb'), (12, 13, 6, 15, 7))
>>> s_tuples = sorted(zip(finger_names, finger_lengths), key=lambda x: x[1])
>>> finger_names, finger_lengths = zip(*s_tuples)
>>> finger_names, finger_lengths
(('pinky', 'thumb', 'pointer', 'ring', 'middle'), (6, 7, 12, 13, 15))
然而,您可能应该在数据结构中链接它们,而不是依赖它们的顺序来关联它们,这是正确的
上述策略(使用键
)在这种情况下仍然有效,但不需要使用zip(*s_tuples)
来解除它们之间的关联
另一方面,如果你想把它们分开,有一个我以前忘记的一行解决方案
finger_lengths, finger_names = zip(*sorted(zip(finger_lengths, finger_names)))
或者,如果要就地排序,请保存一个复制操作:
s_tuples = zip(finger_lengths, finger_names)
s_tuples.sort()
finger_lengths, finger_names = zip(*temp)
您可以使用包含所有三个属性的元组的单一列表,以便在排序期间将它们保持在一起。使用现有数据结构对排序代码执行此操作的一个简单方法是使用
zip
将它们组合起来,然后像这样解包
l = zip(finger_lengths, finger_names, nail_sizes)
l.sort()
finger_lengths, finger_names, nail_sizes = zip(*l)
如果指甲尺寸是空的,这就不起作用了,所以即使没有,你也应该用零填充它,比如
nail\u size=[0]*5
。如果您想将数据结构保持为单独的列表,我建议这样做。否则,如果您不介意将其重新组织为更面向对象,那么最好按照Nick所说的做,并创建一个finger类。我对给定手指长度的手的图片非常感兴趣……您的数据结构是错误的。您需要有一个单独的列表,其中每个项目都有3个属性:fingerName、fingerLength和nailSize。然后在排序时,所有关联的属性都保存在一起。或者你有一个以fingerName为键的dict。但是把一个手指的所有属性放在一起。@DavidHeffernan你说得对,不过这只是一个例子。我的真实数据更复杂。对不起-应该说清楚这只是一个示例类。真正的代码更复杂。@mlissner:很难判断一个人应该如何使用与真正的代码明显不同的示例代码来实现这一点我特别感兴趣的是,任何一个类都有一个“很好的理由”拥有相同维度但独立的列表。