2016-05-25 112 views
0

我有一個地址簿,並且希望高效地打印所有(可能多個)條目, 。有條件地從python中的文件讀取一行代碼

的條目具有以下結構:

Johnsen 
Paul 
First Street 
313 
94134 
State1 
1343154622525 
[email protected] 

Parker 
Peter 
Scnd Street 
44 
91347 
State2 
1343154622525 
[email protected] 

... 

到目前爲止我的代碼如下所示:

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線塊的起始行閱讀(包括空白線)。 現在我想知道如何生成和使用一個序列,該序列會再次打開文件並只讀取匹配的塊以查找。 我很確定這也是一個更有效的方法,我很好奇。

感謝您的幫助。

+0

線條不是很有用......要正確地做到這一點,你需要在文件中實際的字節偏移量......但也許看看'shelve'模塊,這是一個非常容易(但不完美)的方式做一些類似的事情,做一些前期工作...... –

回答

0

您可以隨時將文件加載到字典中,其中鍵是l_name,數據就是一切。我爲你寫了一小段工作部分。我建議創建一個類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') 
0

如果你的文件足夠小,以適應到內存,可以存儲在一個字典中的數據,每個姓氏對應一個或多個項的列表:

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 
# [email protected] 

測試。 txt

Johnsen 
Paul 
First Street 
313 
94134 
State1 
1343154622525 
[email protected] 

Parker 
Peter 
Scnd Street 
44 
91347 
State2 
1343154622525 
[email protected] 
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 

關於避免通過文本文件的每一行遍歷所有suggetions的高度讚賞。