在Python中从文本文件获取属性

在Python中从文本文件获取属性,python,text,python-2.7,python-3.x,Python,Text,Python 2.7,Python 3.x,所以我正在做一个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 ret

所以我正在做一个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.    
关于如何实现这一点,有什么线索吗?

您可以查看集合中的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:

我建议不要尝试搜索文件本身。这是一种非常复杂的搜索,通常由数据库系统来实现这种功能。如果需要这样做,请考虑将应用程序切换到SQLite或另一个轻量级数据库。

可以查看集合中的NAMEDUTPLE类。您将希望使每个条目成为一个命名的耦合,并将字段作为属性。命名的元组可能如下所示:

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:


我建议不要尝试搜索文件本身。这是一种非常复杂的搜索,通常由数据库系统来实现这种功能。如果需要这样做,请考虑将应用程序切换到SQLite或另一个轻量级数据库。

首先,这是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]是一个列表。如果仅构建从属性名称到索引的映射,则可以执行以下操作:

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])

首先,这是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]是一个列表。如果仅构建从属性名称到索引的映射,则可以执行以下操作:

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])

这太完美了!谢谢你的帮助。这太完美了!谢谢你的帮助。