有条件地从python中的文件读取一行行

时间:2016-05-25 14:35:37

标签: python io conditional readline

我有一个地址簿,想要打印所有(可能是多个)条目, 对于给定的“姓氏”有效。

条目具有以下结构:

Johnsen  
Paul  
First Street  
313  
94134  
State1  
1343154622525  
myemail101@mail.com  

Parker  
Peter  
Scnd Street  
44  
91347  
State2  
1343154622525  
myemail224@mail.com  

...

到目前为止,我的代码如下所示:

print("1) Look up by last name")
print("2) Add a person to address book")
print("3) Quit App")

choice = int(input("Enter your choice (1/2/3): "))
if choice == 1:
    lname = input("Enter last name: ")

    addressbook = open("addressbook.txt", "r")

    import itertools
    lnameLines = itertools.islice(addressbook, 0, None, 9)
    matchingLines = []
    lineNumber = 0
    for n in lnameLines:
        if lname.lower() == n.rstrip().lower():
            matchingLines.append(lineNumber)
    lineNumber = lineNumber + 9
print(matchingLines)

这产生的是匹配的9行块的起始行(包括空白行)。 现在我想知道如何生成和使用一个可以再次打开文件的序列,并只读取匹配的块来查找。 我很确定我对此有一种更有效的方法。我很好奇。

感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

您始终可以将文件加载到dict中,其中key为l_name,data为所有内容。我为你写了一个小工作部分。我建议创建一个类Address_book,它具有加载数据,搜索,添加数据和写回数据的功能。这将是简单而直接的,但我不会为你做任何事情!

def load_book(book):
    #assuming your layout never changes

    f = open(book, 'rb').readlines()
    ind = 0

    for i in f:
        if i == '\r\n': #find the empty line seperating each person
            f[ind] = '--'
        ind += 1

    f = [x.split(':') for x in ''.join(f).replace('\r', '').replace('\n', '').replace('  ', ':').lower().split('--')]

    data = {}
    for i in f:
        data[i[0]] = list(x for x in i if i != '')

    return data

def search_book(book, person):
    try:
        return book[person.lower()]
    except:
        for i in book:
            if person.lower() in i:
                return book[i]
        else:
            raise KeyError

book = load_book('add')
print search_book(book, 'Parker')

答案 1 :(得分:0)

如果你的文件足够小以适应内存,你可以将数据存储在一个dict中,其中每个姓氏对应一个或多个条目的列表:

from collections import defaultdict

with open('test.txt') as f:
    dct = defaultdict(list)
    for block in f.read().split('\n\n'):
        dct[block[:block.find('\n')].strip()].append(block)


def lookup(last_name):
    print('\n\n'.join(dct.get(last_name, [])))


# In [61]: q.lookup('Johnsen')
# Johnsen  
# Paul  
# First Street  
# 313  
# 94134  
# State1  
# 1343154622525  
# myemail101@mail.com  

的test.txt

Johnsen  
Paul  
First Street  
313  
94134  
State1  
1343154622525  
myemail101@mail.com  

Parker  
Peter  
Scnd Street  
44  
91347  
State2  
1343154622525  
myemail224@mail.com

答案 2 :(得分:0)

感谢您提出的建议。我非常欣赏建立地址簿类的想法以及内存中的方法,尽管不是我需要的。

我的 - 不是最有效但最简单的 - 解决方法如下:

choice = int(input("Enter your choice (1/2/3): "))
if choice == 1:
lname = input("Enter last name: ")

book = open("addressbook.txt", "r")

for i, line in enumerate(book):
    if (i % 9 == 0 and 
        lname.lower() == line.rstrip().lower()):
        load = 9
    if load > 0:
        print(line.rstrip())
        load = load - 1

有关避免迭代遍历文本文件的每一行的任何建议都受到高度赞赏。