Python没有在第一行以外的任何行上找到短语?

时间:2015-09-22 19:16:09

标签: python

我正在尝试创建一个python联系人管理器,我创建了一个搜索contacts.txt文件的函数。它可以成功找到你或者列表中第一个应该是你的联系人,但它找不到其他联系人。我不知道为什么或如何发生这种情况。

功能

def readFile(self):

    f = open('contacts.txt', 'r')
    lines = f.readlines()
    cmd = str(input("Type in a contact REFERENCE name.\n"))
    lookup = cmd

    with open('contacts.txt') as myFile:
        for num, line in enumerate(myFile, 1):
            if lookup.upper() in line:

                print(lines[num - 1])
                print(lines[num])
                print(lines[num + 1])
                print(lines[num + 2])
                print(lines[num + 3])

                self.managerMenu()

            else:
                print("Contact not found.")
                self.managerMenu()

contacts.txt

Contact: YOU
    First Name: FELIX
    Last Name: MARTIN
    Number: (555)-555-5555
    Address: 123 SESAME STREET
Contact: DAD
    First Name: JOHN
    Last Name: SMITH
    Number: (555)-555-5555
    Address: 123 SESAME STREET

当我运行该文件时,键入readfile然后you会生成以下内容:

Available Commands: Info, ReadFile, DeleteContact, EditContact, AddContact, quit()
readfile
Type in a contact REFERENCE name.
you
Contact: YOU

    First Name: FELIX

    Last Name: MARTIN

    Number: (555)-555-5555

    Address: 123 Sesame Street

但是当我使用DAD联系人做同样的事情时:

Available Commands: Info, ReadFile, DeleteContact, EditContact, AddContact, quit()
readfile
Type in a contact REFERENCE name.
dad
Contact not found.

我在c9.io上运行Python 3.4。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

问题在于您检查的每一行是否O(|V| log |E|)都在该行中,如果是,则打印出来,如果您不是在调用lookup.upper(),我猜打印出你程序中的菜单。

你无论如何都会打电话给self.managerMenu(),所以你应该只在完成整个文件后调用它。示例 -

self.managerMenu()

请注意,我将def readFile(self): f = open('contacts.txt', 'r') lines = f.readlines() cmd = str(input("Type in a contact REFERENCE name.\n")) lookup = cmd with open('contacts.txt') as myFile: for num, line in enumerate(myFile, 1): if lookup.upper() in line: print(lines[num - 1]) print(lines[num]) print(lines[num + 1]) print(lines[num + 2]) print(lines[num + 3]) break else: print("Contact not found.") self.managerMenu() 移动到与else循环相同的缩进级别,这使其成为for构造,for..else块仅在我们执行时执行不要使用else来打破循环,这意味着我们没有找到任何匹配的行。

同样读取文件两次效率非常低,您可以使用break为文件创建迭代器。示例 -

iter()

请注意,如果def readFile(self): lookup = input("Type in a contact REFERENCE name.\n") with open('contacts.txt') as myFile: my_file_iter = iter(myFile) for num, line in enumerate(my_file_iter, 1): if lookup.upper() in line: print(line) print(next(my_file_iter)) print(next(my_file_iter)) print(next(my_file_iter)) print(next(my_file_iter)) break else: print("Contact not found.") self.managerMenu() 确实是菜单从您可以再次进入此self.managerMenu()方法开始打印,那么这将是一个糟糕的菜单方式,因为在运行程序之后你的堆栈会很大(因为你正在使用递归菜单),退出也很复杂。我建议你改用readFile(self)循环。

答案 1 :(得分:0)

不要真正看到任何会导致你所描述的行为的东西,但是我会在if语句中创建line.upper(),这样你就可以完全确定它会忽略大写的情况。双方。以防于contacts.txt可能是DaD或Dad而不是DAD。

答案 2 :(得分:-1)

对于正则表达式来说,这听起来好得多。请考虑以下示例。

import re
contacts_text = """Contact: YOU
    First Name: FELIX
    Last Name: MARTIN
    Number: (555)-555-5555
    Address: 123 SESAME STREET
Contact: DAD
    First Name: JOHN
    Last Name: SMITH
    Number: (555)-555-5555
    Address: 123 SESAME STREET"""
parsed_contacts = re.compile(r'(?i)(\s*contact\s*:?\s*)(\w*)(.*?)(?=contact|$)', flags=re.DOTALL).findall(contacts_text)
contacts = {}
search_fields = {'First Name': r'(?i)(\s*first\s*name\s*:?\s*)(.*?)(\n)',
                 'Last Name': r'(?i)(\s*last\s*name\s*:?\s*)(.*?)(\n)',
                 'Number': r'(?i)(\s*number\s*:?\s*)(.*?)(\n)',
                 'Address': r'(?i)(\s*address\s*:?\s*)(.*?)(\n)'}

for pc in parsed_contacts:
    contact_header = pc[1]
    contacts[contact_header] = {}
    for seach_id, regex in search_fields.items():
        match_obj = re.search(regex, pc[2])
        if match_obj:
            contacts[contact_header][seach_id] = match_obj.group(2)
        else:
            contacts[contact_header][seach_id] = None
print contacts