Python - 按首字母分隔列表

时间:2014-07-01 13:04:56

标签: python sorting pygame

我希望能够将联系人列表与联系人姓名的第一个字母分开,即

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

我真的不知道如何解决这个问题。

1 个答案:

答案 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坐标。