我第一次在这里问一些事情。我有一个名称的文本文件,每行1个名字,我正在读入列表,然后复制该列表两次,第一次删除\ n&n;以及第二次小写名单。然后我问用户一个搜索词,并将他们的输入转换为小写,然后搜索列表的小写版本,然后我得到匹配的索引,并使用它来显示该非小写版本将项目列回给用户(因此他们可以键入例如anivia并返回Anivia)。这工作正常,但我确定我的代码非常糟糕。我想要做的是为列表文件中的某些名称添加特定的缩写,并接受这些缩写作为输入,但仍然显示全名。例如,用户输入" mumu"并且它看到该列表有Amumu - mumu,参考Amumu。我怎么能接受这种缩减?还有其他一些案例,比如“财富小姐”的mf或者Kha&#Z; Z的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和编程一般都很陌生。感谢您提供任何帮助,对不起这么长的帖子感到抱歉。
答案 0 :(得分:2)
好的,这是一个修改后的答案,假设有一个文件包含this开头所示的名称和缩写。
它本质上是做一个大的查找表,它将文件中的任何缩写以及小写的名称本身映射到每行开头的名称。
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
答案 1 :(得分:0)
首先,您应该使用有用的名称。因此,而不是list2
将其称为lower_names
等等。
其次,您可以通过一次in
调用替换index
运算符和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]
在蟒蛇哲学中经常说,要求宽恕比获得许可更好。 :)
另一个重要的事情,这只是假设你想要将小写名称与其“真实”名称相匹配,你需要一个字典。字典将键映射到值,因此您在此处需要将每个小写名称(键)映射到实际名称(值)。它可以这样定义(我看你熟悉一个衬里):
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]
。
至于额外的功能,我会选择第二个选项,即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子句执行等效操作,但这会产生太多嵌套,不推荐使用。