1

テキスト ファイルがあり、それを Python の辞書にロードしたいと考えています。

テキストは、タブ区切りで次のようになります。

形態 投与量の参考文献 注射剤 20,000 単位/ml リクエミン ナトリウム ヘパリン ナトリウム注射剤。注射 40,000 単位/ml リクエミン ナトリウム ヘパリン ナトリウム注射剤。注射 5,000 単位/ml リクエミン ナトリウム ヘパリン ナトリウム

現在、私のコードは次のようになっていますが、機能しません (リスト インデックスが範囲外で、辞書に何も​​プッシュされていません)。プログラマーではなく、どこが間違っているのかわかりません。助けてくれてありがとう。

import sys

def load_medications(filename):
    meds_dict = {}
    f = open(filename)
    l = " "
    # print f.read()
    for line in f:
        fields = l.split("\t")
        ApplNo = fields[0]
        ProductNo = fields[1]
        Form = fields[2]
        Dosage = fields[3]
        ProductMktStatus = fields[4]
        TECode = fields[5]
        ReferenceDrug = fields[6]
            DrugName = fields[7]
        ActiveIngred = fields[8]

        meds = {
                "ApplNo": ApplNo,   
                "ProductNo": ProductNo, 
                "Form": Form,
                "Dosage": Dosage,   
                "ProductMktStatus": ProductMktStatus,
                "TECode": TECode,
                "ReferenceDrug": ReferenceDrug, 
                "DrugName": DrugName,
                "ActiveIngred": ActiveIngred
            }       
        meds_dict[DrugName] = meds
    f.close()
    return meds_dict


def main():
    x = load_medications("druglist.txt")
    print x



if __name__ == "__main__":
    main()
4

7 に答える 7

2

line.splitの代わりに試してみてくださいl.split

于 2012-08-09T22:50:10.067 に答える
2

標準ライブラリの CSV モジュールを使用すると、このデータを簡単に解析できる場合があります。タブを区切り文字;として、行終端記号として使用すると、投稿したファイルの解析に問題はありません。

DictReaderを使用すると、行を読みやすくなります (line['ApplNo']の代わりにとして参照できますline[0])。

残念ながら、ファイル内のヘッダーがコード内で呼び出したいものにマップされているようには見えません。そのため、辞書にあったものに基づいてフィールドの名前を自分で割り当てる必要があります。

于 2012-08-09T22:55:22.687 に答える
1

csv.DictReaderファイルの先頭に適切な見出し行があると仮定すると、次のように簡単に辞書を作成できるはずです。

def load_medications(filename):
    reader = csv.DictReader(open(filename), delimiter='\t')
    meds = {}
    for row in reader:
        meds[row['DrugName']] = row
    return meds

ファイルに見出し行がない場合は、フィールド名をDictReader初期化子に渡すことができます。

fields = ["ApplNo", "ProductNo", "Form", "Dosage", "ProductMktStatus"
          "TECode", "ReferenceDrug", "DrugName", "ActiveIngred"]
reader = csv.DictReader(open(filename), delimiter='\t', fieldnames=fields)
于 2012-08-09T22:58:24.033 に答える
0

フィールド名はすべて有効な Python 識別子なので、データを辞書ではなく名前付きタプルに読み込んでみませんか?

data = """Form Dosage ReferenceDrug drugname activeingred INJECTABLE; INJECTION 20,000 UNITS/ML LIQUAEMIN   SODIUM HEPARIN  SODIUM  INJECTABLE; INJECTION   40,000 UNITS/ML LIQUAEMIN   SODIUM HEPARIN  SODIUM  INJECTABLE; INJECTION   5,000 UNITS/ML  LIQUAEMIN   SODIUM HEPARIN  SODIUM  INJECTABLE""".split('; ')

from collections import namedtuple

# define class DrugData as a namedtuple, using the headers from data[0]
DrugData = namedtuple("DrugData", data[0])

# use a list comprehension to create a DrugData for each data line
druglist = [DrugData(*line.split('\t')) for line in data[1:]]

# access each tuple in druglist, using attribute access to individual fields
for d in druglist:
    print "%s | %s | %s" % (d.ReferenceDrug, d.Form, d.Dosage)

版画:

LIQUAEMIN | INJECTION | 20,000 UNITS/ML
LIQUAEMIN | INJECTION | 40,000 UNITS/ML
LIQUAEMIN | INJECTION | 5,000 UNITS/ML

編集:

元の質問を振り返ると、これらすべてのエントリの単一の辞書を作成したいようですdrugname。残念ながら、辞書キーは一意である必要があり、あなたの例では、3 つのエントリすべてが同じdrugnameです。のタプルなど、これらすべての値を処理する dict の真に一意のキーを作成するには、2 つ以上のフィールドを組み合わせる必要がある場合があります(drugname, Dosage)

または、デザインを少し変更して、それぞれが一致する値のリストdrugnameを指すようにします。最も簡単なのは、dict の代わりに defaultdict を使用することです。これにより、新しいエントリが空のリストで自動的に初期化されます。コードに import ステートメントを追加します。

from collections import defaultdict

meds_dict の宣言を次のように変更します。

meds_dict = defaultdict(list)

つまり、まだ表示されていない新しいキーは、defaultdict の引数として提供された関数/クラスを使用して初期化されます。この場合はlist.

次に、新しいエントリを meds_dict に追加するには、「=」で割り当てる代わりに、一致するすべての薬/投与量のリストに追加します。

meds_dict[DrugName].append(meds)

これで、任意の DrugName について、一致する Form/Dosage/etc のリストが取得されます。記録。

于 2012-08-10T02:06:19.980 に答える
0

ファイルの列数を過大評価していると思います。ApplNoはどこProductNoですか?

于 2012-08-09T22:51:35.767 に答える
0

あなたは実際に分割しますがl、分割しませんline。あなたがしたい:

def load_medications(filename):
    meds_dict = {}
    with open(filename) as f: # Ensure that the file gets closed
        for line in f:
            fields = line.split("\t") # line, not l
            keys = ["ApplNo", "ProductNo", "Form", "Dosage", "ProductMktStatus",
                    "TECode", "ReferenceDrug", "DrugName", "ActiveIngred",]

            if len(fields) != len(keys):
                raise ValueError("Malformed input line " + repr(line))

            meds = dict(zip(keys, fields))
            meds_dict[meds["DrugName"]] = meds
    return meds_dict

これが機能する理由の詳細については、zipおよび を参照してくださいdict

于 2012-08-09T22:52:03.930 に答える
0

あなたのコードは、特定の薬に 9 つの特性があると想定しているようです。ただし、投稿したサンプル テキスト ファイルには 5 つのプロパティしかありません。を呼び出すとfields = l.split("\t")、「druglist.txt」に 5 つの要素しかないため、5 つの要素だけの配列が返されます。fieldsそのため、5 以上の値でインデックスを作成するとfields[8]、「範囲外のインデックス」例外が発生します。

于 2012-08-09T23:05:51.517 に答える