2013-03-28 22 views
1

因此,我正在製作一個Yu-Gi-Oh數據庫程序。我把所有的信息存儲在一個大的文本文件中。每個怪物chategorized通過以下方式:從Python中的文本文件獲取屬性

|Name|NUM 1|DESC 1|TYPE|LOCATION|STARS|ATK|DEF|DESCRIPTION 

下面是一個實際的例子:

|A Feather of the Phoenix|37;29;18|FET;YSDS;CP03|Spell Card}Spell||||Discard 1 card. Select from your Graveyard and return it to the top of your Deck.| 

所以我做了一個程序,按名稱搜索這個大的文本文件,並將其返回從文本文件中的信息沒有'|'。那就是:

with open('TEXT.txt') as fd: 
     input=[x.strip('|').split('|') for x in fd.readlines()] 
     to_search={x[0]:x for x in input} 
     print('\n'.join(to_search[name])) 

現在我想修改我的計劃,所以我可以尋找怪物的名稱,並選擇哪個屬性我想顯示。所以它看起來像

A Feather of the Phoenix 
Description: 
Discard 1 card. Select from your Graveyard and return it to the top of your Deck.  

任何線索,我怎麼能做到這一點?

回答

0

你可以看collections中的namedtuple類。您將希望使用您的字段作爲屬性的每個條目namedtuple。該namedtuple可能看起來像:

Card = namedtuple('Card', 'name, number, description, whatever_else') 

如集合文檔,namedtuple和CSV工作顯示得很好:

import csv 
for card in map(Card._make, csv.reader(open("cards", "rb"))): 
    print card.name, card.description # format however you want here 

搜索周圍的機制是非常複雜的。例如,如果你想圍繞一個精確匹配構建一個真正的快速搜索,你可以建立一個字典每個屬性你感興趣的:

name_map = {card.name: card for card in all_cards} 
search_result = name_map[name_you_searched_for] 

你也可以做一個startswith搜索:

possibles = [card for card in all_cards if card.name.startswith(search_string)] 
# here you need to decide what to do with these possibles, in this example, I'm just snagging the first one, and I'm not handling the possibility that you don't find one, you should. 
search_result = possibles[0] 

我建議不要試圖搜索文件本身。這是一種非常複雜的搜索,通常由數據庫系統來實現這種功能。如果您需要這樣做,請考慮將應用程序切換到sqlite或其他輕量級數據庫。

5

首先,這是CSV的變體方言,可以用csv模塊解析,而不是嘗試手動完成。例如:

with open('TEXT.txt') as fd: 
    rows = csv.reader(fd, delimiter='|') 
    to_search = {row[1]:row for row in rows} 
    print('\n'.join(to_search[name])) 

您也可能更喜歡使用DictReader,所以每一行是一個dict(鍵控關閉的名稱標題行中,或手動指定的列名,如果你沒有一個):

with open('TEXT.txt') as fd: 
    rows = csv.DictReader(fd, delimiter='|') 
    to_search = {row['Name']:row for row in rows} 
    print('\n'.join(to_search[name])) 

然後,選擇特定屬性:

with open('TEXT.txt') as fd: 
    rows = csv.DictReader(fd, delimiter='|') 
    to_search = {row['Name']:row for row in rows} 
    print(to_search[name][attribute]) 

不過......我不知道這是擺在首位的好設計。你真的想重新閱讀每個查詢整個文件嗎?我認爲將它讀入內存一次更合理,可以反覆使用到一個通用結構中。而事實上,你已經幾乎得到了這樣的結構:

with open('TEXT.txt') as fd: 
    monsters = list(csv.DictReader(fd, delimiter='|')) 
monsters_by_name = {monster['Name']: monster for monster in monsters} 

然後你就可以建立額外的指標,像怪獸的多圖的位置等等,如果你需要他們。


所有這一切,你的原始代碼幾乎可以處理你想要的東西。 to_search[name]list。如果你只是建立一個從屬性名稱到索引的地圖,你可以這樣做:

attributes = ['Name', 'NUM 1', 'DESC 1', 'TYPE', 'LOCATION', 'STARS', 'ATK', 'DEF', 'DESCRIPTION'] 
attributes_by_name = {value: idx for idx, value in enumerate(attributes)} 
# ... 
with open('TEXT.txt') as fd: 
    input=[x.strip('|').split('|') for x in fd.readlines()] 
    to_search={x[0]:x for x in input} 
    attribute_index = attributes_by_name[attributes] 
    print(to_search[name][attribute_index]) 
+0

這是完美的!感謝您的幫助。 – user1985351