1

遊戯王のデータベースプログラムを作っています。すべての情報を大きなテキスト ファイルに保存しています。各モンスターは次のように分類されます。

|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

namedtupleでクラスを見ることができますcollectionsnamedtupleフィールドを属性として各エントリを作成する必要があります。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 に答える