我希望能够将联系人列表与联系人姓名的第一个字母分开,即
A
----------
#All contacts under A
B
----------
#All contacts under B
etc...
我的所有联系人都是Contact
类的实例,它存储在列表中。用于按字母顺序对它们进行排序的代码是
addressBook.contactsList.sort(key = lambda c: (c.lastName, c.firstName) if c.lastName else (c.firstName, ""))
我目前正在与PyGame合作开发GUI,到目前为止,我已经设法打印列表联系人没有问题,除了我现在问的那个。它目前看起来很混乱'因为联系人一次性列在一起,没有任何分隔符以显示清晰度。
我希望生成的分隔符具有我选择的样式,首先使用GUI的其余部分,并向最终用户显示它是分隔符。
用于生成GUI屏幕的三个类定义如下:
class Contact():
def __init__(self, firstName, lastName, address, groupType,
telephone, mobile, email, photoField):
self.firstName = firstName
self.lastName = lastName
self.address = address
self.groupType = groupType
self.telephone = telephone
self.mobile = mobile
self.email = email
self.photoField = photoField
def showDetails(self):
print("First Name:\t", self.firstName)
print("Last Name:\t", self.lastName)
print("Address:\t", self.address)
print("Telephone:\t", self.telephone)
print("Mobile:\t", self.mobile)
print("Email:\t", self.email)
@classmethod
def from_input(cls):
firstName = input("First Name: ")
lastName = input("Last Name: ")
address = input("Address: ")
telephone = input("Telephone: ")
mobile = input("Mobile: ")
email = input("Email: ")
return cls(firstName, lastName, address, None,
telephone, mobile, email, None)
class AddressBook():
def __init__(self):
self.contactsList = pickle.load(open("save.p", "rb"))
def addContact(self, contact = None):
if contact is None:
contact = Contact.from_input()
self.contactsList.append(contact)
pickle.dump(self.contactsList, open("save.p", "wb"))
def delContact(self, contact = None):
if contact is None:
search = input("Search: ")
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
indexed = self.contactsList.index(i)
del self.contactsList[indexed]
pickle.dump(self.contactsList, open("save.p", "wb"))
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
def contactInfo(self, contact = None):
if contact is None:
search = input("Search: ")
print()
#display contact information
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
i.showDetails()
print()
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
else:
print("No contacts\n")
def contactSearch(self, contact = None):
if contact is None:
search = input("Search: ")
print()
for i in self.contactsList:
if (i.firstName.lower() == search.lower()) or (i.lastName.lower() == search.lower()):
print(i.firstName, i.lastName)
print()
elif (i.firstName.lower() != search.lower()) or (i.lastName.lower() != search.lower()):
continue
else:
print("No contacts\n")
class MainPage(Page):
def __init__(self, screen = pygame.display.set_mode((320, 480)), caption = pygame.display.set_caption("Contacts"), title = "Contacts"):
Page.__init__(self, screen, caption)
self.title = title
def style(self):
Page.style(self)
titleFont = pygame.font.SysFont("trebuchet ms", 38)
textSurface = titleFont.render(self.title, True, (255,255,255))
self.screen.blit(textSurface, (5, 18))
AddButton().shape()
#Presenting contacts on page
def printContacts(self):
addressBook = AddressBook()
addressBook.contactsList
addressBook.contactsList.sort(key = lambda c: (c.lastName, c.firstName) if c.lastName else (c.firstName, ""))
contactFont = pygame.font.SysFont("trebuchet ms", 18)
x = 80
for i in addressBook.contactsList:
name = i.firstName + " " + i.lastName
textName = contactFont.render(name, True, (0,0,0))
pygame.draw.line(self.screen, (210,210,210), (5,(x+20)), (320, (x+20)), 1)
self.screen.blit(textName, (5, x))
x += 30
我真的不知道如何解决这个问题。
答案 0 :(得分:1)
您可以使用groupby
对数据进行分组:
from itertools import groupby
...
# group contactsList by first letter of lastName
for (key, g) in groupby(addressBook.contactsList, lambda c: c.lastName[0]):
# draw divider here
groupName = contactFont.render(key, True, (0,0,0))
self.screen.blit(groupName, (5, x))
pygame.draw.line(self.screen, ...)
for i in g:
name = i.firstName + " " + i.lastName
textName = contactFont.render(name, True, (0,0,0))
pygame.draw.line(self.screen, (210,210,210), (5,(x+20)), (320, (x+20)), 1)
self.screen.blit(textName, (5, x))
x += 30
此外,您的变量x
似乎应该命名为y
,因为它代表y
坐标。