1

ここで初めて何かを尋ねます。リストに読み込んでいる名前のテキストファイルがあります。1回目は\nを削除し、2回目はリストを小文字にします。次に、ユーザーに検索語を要求し、入力を小文字に変換してから、リストの小文字バージョンを検索します。次に、一致のインデックスを取得し、それを使用して、その非小文字バージョンを表示します。アイテムをユーザーにリストします(たとえば、aniviaと入力して、Aniviaを取得できます)。これは正常に機能していますが、私のコードはかなり悪いと確信しています。私がやりたいのは、リストファイル内のいくつかの名前に特定の略語を追加し、それらの略語を入力として受け入れますが、それでもフルネームを表示します。たとえば、ユーザーは「mumu」と入力します そして、リストにAmumuが含まれていることがわかります-Amumuを参照するためのmumu。どうすればその略語を受け入れることができますか?また、MissFortuneのmf​​やKha'Zixのkhaなどの他のケースもあります。2番目のファイルに略語のリストが含まれていると思いましたが、それは非常に無駄に思え、より良い方法があると確信しています。これまでの私の悪いコードは次のとおりです。

f = open("champions.txt") #open the file
list = f.readlines() #load each line into the list
#print list
list2 = [item.rstrip('\n') for item in list] #remove trailing newlines in copy list
list3 = [item.lower() for item in list2] #make it all lowercase

print "-------\n", list2 #print the list with no newlines just to check

print "which champ" #ask user for input
value = raw_input().lower() #get the input and make it lowercase
if value in list3: #check list for value and then print back a message using that index but from the non-lowercase list
    pos = list3.index(value)
    print "list contains", list2[pos]
else: #if the input doesn't match an item print an error message
    print "error"

必要な方法で機能したら、これをすべてメインファイルの関数に入れます。基本的に、テキストファイルの一部の行を変更して、有効な代替略語を使用し、その略語を受け入れて、フルネームをユーザーに表示できるようにします。たとえば、略語が含まれているセカンダリテキストファイルの行の1つに、次の行があります。

Kog'Maw - kogmaw, kog, km

どうすれば私が持っているものを単純化し、その機能を追加できますか?どこから始めればよいのかよくわかりません。Pythonとプログラミング全般にかなり慣れていません。あなたが提供できるどんな助けにも感謝します、そのような長いポストを申し訳ありません。

4

2 に答える 2

2

OK、これは、この冒頭に示されているように、名前と略語を含むファイルが1つあることを前提とした修正された回答です。

基本的には、ファイル内の任意の略語と小文字の名前自体を各行の先頭の名前にマップする大きなルックアップテーブルを作成します。

lookup = {}
with open("champions.txt") as f:
    for line in f:
        line = line.rstrip().split('-', 1)
        if not line: continue # skip any blank lines

        name = line[0].strip()
        lookup[name.lower()] = name
        if len(line) == 2:  # any alternative names given?
            for item in line[1].split(','):
                lookup[item.strip()] = name

print 'lookup table:'
for alt_name, real_name in sorted(lookup.items()):
    print '{}: {}'.format(alt_name, real_name)
print

while True:
    print "which champ (Enter to quit): "  # ask user for input
    value = raw_input().lower()  # get the input and make it lowercase
    if not value: break

    real_name = lookup.get(value)
    if real_name:
        print 'found:', value, '-->', real_name
    else:
        print 'error: no match for', value
于 2012-11-21T18:13:31.967 に答える
0

まず、有用な名前を使用する必要があります。だから、それをlist2呼ぶ代わりにlower_names、など。

次に、inオペレーターを置き換えて、 index1回の呼び出しで呼び出すことができindexます。気付いた場合は、に電話をかけるsome_list.index(item_which_does_not_exist)valueError、そのアイテムがリストにないというメッセージが表示されます。これを行う最も「pythonic」な方法はtry、インデックスを取得するexceptことです。失敗した場合は、別のことを行います。

ifしたがって、パーツを次のように置き換えることができます。

try:
    pos = list3.index(value)
except ValueError:
    print 'error'
else:
    print 'everything is ok. there was no exception raised'
    print 'list contains', list2[pos]

Pythonの哲学では、許可よりも許しを求める方がよいとよく言われます。:)

もう1つの重要なことは、小文字の名前をその「実際の」名前と一致させたいということだけを想定しているため、ここに辞書が必要です。辞書はキーを値にマップするので、ここにあるのは、各小文字の名前(キー)を実際の名前(値)にマップする場合です。これは次のように定義できます(あなたは1つのライナーに精通していると思います):

name_map = {item.lower(): item for item in (line.strip() for line in f)}

したがって、を使用する代わりにreadlines、ファイルを直接ループすることができます。これはPythonの余分な砂糖です。

そして、次のようなことを行うことができます:value in name_mapまたはreal_name = name_map[value]

追加機能については、2番目のオプションであるname - nickname1,nickname2。したがって、実行する必要があるのは、各行を読み取り、ダッシュ-(または名前で使用されない他の文字)で分割し、2番目の部分をコンマで分割して各名前だけにすることです。まとめ:

name_map = {}
nick_map = {}
for line in f:
    parts = line.strip().split('-')
    name = parts[0].strip()
    nicks = {n.strip(): name for n in parts[1].split(',')}
    name_map[name.lower()] = name
    nick_map.update(nicks)

# To check a name:
if value in name_map:
   # Exact match
elif value in nick_map:
   # Nickname match
else:
   # No Match

try /except / else句を使用して同等の処理を行うこともできますが、ネストが多すぎるため、お勧めしません。

于 2012-11-21T18:18:36.463 に答える