1

所以我正在制作一个 Yu-Gi-Oh 数据库程序。我将所有信息都存储在一个大文本文件中。每个怪物都按以下方式分类:

|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.    

关于我如何做到这一点的任何线索?

4

2 回答 2

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])
于 2013-03-28T19:54:14.647 回答
0

你可以看看中的namedtuplecollections。您将希望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 或其他轻量级数据库。

于 2013-03-28T19:53:57.740 回答