在我的程序中,我想先按名字,姓氏,名字命名所有联系人。
我已经获得了代码,它为我做了但是它并没有完全符合我的要求。
例如,如果我有一个按照当前代码的顺序排列的名称列表,它将是这样的:
Luke
Riyaan
Amanda Benson
正如您所看到的,代码仍然需要None
作为值进行排序,我想要的是:
Amanda Benson
Luke
Riyaan
所以基本上,如果姓氏返回None
,那么我希望程序按照具有姓氏的对象的优先顺序排序第一个名称。
这是我目前用来对名称进行排序的代码:
import operator
...
addressBook = AddressBook()
addressBook.contactsList
addressBook.contactsList.sort(key = operator.attrgetter("lastName", "firstName"))
答案 0 :(得分:3)
您需要一个自定义排序功能,然后在缺少姓氏时,将您的名字作为元组中的第一个值返回:
def name_sort(contact):
if contact.lastName:
return contact.lastName, contact.firstName
return contact.firstName, ''
addressBook.contactsList.sort(key=name_sort)
您可以使用lambda
和条件表达式将其纳入sort()
调用:
addressBook.contactsList.sort(key=lambda c: (c.lastName, c.firstName) if c.lastName else (c.firstName, ''))
我在这里为这两种情况生成一个2值元组,但是对于无名字的情况的单元素元组也应该足够了。
如果这是您感兴趣的唯一排序顺序,您可能需要查看提供rich comparison functions,以便您可以在没有密钥的情况下对对象进行排序;然后比较对象本身并提供排序顺序。
您不必实施所有丰富的比较方法;你需要的只是一个,加上__eq__
(相等测试)和@functools.total_ordering()
class decorator:
from functools import total_ordering
@total_ordering
class Contact(object):
# ...
def __eq__(self, other):
if self.lastName != other.lastName:
return False
return self.firstName == other.firstName
def __lt__(self, other):
if not self.lastName:
if not other.lastName:
return self.firstName < other.firstName
return self.firstName < other.lastName
return (self.lastName, self.firstName) < (other.lastName, other.firstName)
答案 1 :(得分:0)
执行此操作的最佳方法是在您的(我猜)Contact
课程中实施the rich comparison magic methods:
class Contact(object):
def __init__(self, first_name, last_name=""):
self.first_name = first_name
self.last_name = last_name
def __repr__(self): # to make the demo clearer!
if not self.last_name:
return str(self.first_name)
return "{0.first_name} {0.last_name}".format(self)
def __eq__(self, other):
return (self.first_name == other.first_name and
self.last_name == other.last_name)
def __lt__(self, other):
if self.last_name and other.last_name:
if self.last_name == other.last_name:
return self.first_name < other.first_name
return self.last_name < other.last_name
else:
if other.last_name:
return self.first_name < other.last_name
return self.first_name < other.first_name
现在您只需使用sorted
和list.sort
不带参数:
>>> contacts_list = [Contact("Luke"), Contact("Riyaan"), Contact("Amanda", "Benson")]
>>> sorted(contacts_list)
[Amanda Benson, Luke, Riyaan]