1

我第一次在这里问东西。我有一个名称文本文件,每行一个名称,我正在读入一个列表,然后将该列表复制两次,第一次删除\n,第二次将列表小写。然后我向用户询问一个搜索词,并将他们的输入转换为小写,然后搜索列表的小写版本,然后我得到匹配的索引,并使用它来显示那个的非小写版本将项目返回给用户(以便他们可以键入例如 anivia 并取回 Anivia)。这工作正常,但我确定我的代码很糟糕。我想做的是为列表文件中的某些名称添加特定的缩写,并接受这些缩写作为输入,但仍显示回全名。例如,用户输入“mumu” 它看到列表中有 Amumu - mumu,以引用 Amumu。我怎么能接受这个缩写?还有其他情况,例如幸运小姐的 mf 或卡兹克的 kha。我想也许有第二个文件包含缩写列表,但这似乎很浪费,我相信有更好的方法。到目前为止,这是我的错误代码:

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"

一旦它按我需要的方式工作,我就把它全部放入我的主文件中的某个函数中。基本上我想更改我的文本文件中的一些行以具有有效的替代缩写,并且能够接受其中的那些,并且仍然将全名显示给用户。例如,我的辅助文本文件中具有缩写的行中有一行:

Kog'Maw - kogmaw, kog, km

我怎样才能简化我所拥有的并添加该功能?我不确定从哪里开始,我对 python 和一般编程很陌生。感谢您提供的任何帮助,对于这么长的帖子感到抱歉。

4

2 回答 2

2

好的,这是一个修改后的答案,假设有一个包含名称和缩写的文件,如本文开头所示

本质上,它所做的是制作一个大型查找表,将文件中的任何缩写加上小写的名称本身映射到每行开头的名称。

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接线员index,只需一index通电话即可。如果你注意到了,调用 tosome_list.index(item_which_does_not_exist)valueError提示该项目不在列表中。最“pythonic”的方法是通过trying 获取索引,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 哲学中经常说,请求宽恕比请求许可更好。:)

另一件重要的事情,这只是假设您想将小写名称与其“真实”名称匹配,您需要一个字典。字典将一个键映射到一个值,因此您在这里遇到的情况是您希望每个小写名称(键)映射到真实名称(值)。它可以这样定义(我看到你熟悉一个衬垫):

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

因此,readlines您可以直接遍历文件,而不是使用 。这是 Python 中的额外糖分。

然后,您可以执行以下操作:value in name_mapreal_name = name_map[value].

至于额外的功能,我会选择你的第二个选项,即name - nickname1,nickname2. 所以你需要做的是:阅读每一行,用破折号分隔-(或任何其他不会在名称中使用的字符),然后用逗号分隔第二部分以单独使用每个名称。包起来:

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 回答