我有以下代码,试图将文件内容读入列表(此位有效),然后显示接受消息,如果银行详细信息(用户和相应的号码)匹配。
e.g。如果用户名:customer1和account_number:1输入>>对文件中的每个客户和帐号进行授权等等。
文件详情
def strip_split_read_from_file():
bankdetails=[]
with open("bankdetails.txt","r") as f:
for line in f:
line=line.rstrip() #r strip removes the new line character from the right side of the string
split_line=line.split(",")
for field in split_line:
bankdetails.append(field)
accessgranted=False
while accessgranted==False:
username=input("username:")
password=input("account no:")
for i in bankdetails:
if username==bankdetails[i] and password==bankdetails[i+1]:
accessgranted=True
break
else:
accessgranted=False
if accessgranted==True:
print("Access Granted")
else:
print("Sorry, wrong credentials")
代码
if username==bankdetails[i] and password==bankdetails[i+1]:
TypeError: list indices must be integers, not str
错误
{{1}}
对于答案和教学/学习目的,我想要以下
使用现有的提供的代码
关于以尽可能最有效的方法实现同一目标的替代方法的建议
答案 0 :(得分:1)
for i in bankdetails:
表示i
将成为bankdetails中的每个元素,而不是它将成为元素的位置。如果您希望它成为位置,则必须执行for i in len(bankdetails)
,因为len()
是获取数据结构长度的函数。但是,由于每次都有两个字段,我建议使用while结构,如下所示:
total = len(bankdetails) - 1
i = 0
while i < total:
if username==bankdetails[i] and password==bankdetails[i+1]:
accessgranted=True
break
else:
accessgranted=False
i += 2
但是,如果列表中有大量条目,则迭代所有条目可能会花费大量时间。为了避免这种情况,使用字典是最好的选择:检查项目是否在其中的速度要快得多,并且您不需要迭代来查找与之关联的值。
如果您不知道字典是如何工作的,它有点像列表,除非它们没有被排序,而您查找项目的方式是检查与键关联的值。让我们更清楚一点。在您的文件中,您有:
customer1,1
customer2,2
customer3,3
customer4,4
customer5,5
将它们添加到字典中的方法是:
bankdetails={} #Notice that they're initialized as {}
with open("bankdetails.txt","r") as f:
for line in f:
line=line.rstrip() #r strip removes the new line character from the right side of the string
split_line=line.split(",")
username = split_line[0]
password = split_line[1]
bankdetails[username] = password
这样,bankdetails将包含{'customer1': '1', 'customer2': '2', ... }
而且,要查找用户及其密码,您必须执行此操作:
username=input("username:")
password=input("account no:")
if username in bankdetails:
if bankdetails[username]==password:
accessgranted=True
break
else:
accessgranted=False
这将完全符合您的要求,但如果您有大量条目,则会更快。
答案 1 :(得分:1)
def strip_split_read_from_file():
bankdetails=[]
with open("files.txt","r") as f:
for line in f:
line=line.rstrip()
split_line=line.split(",")
for field in split_line:
bankdetails.append(field)
accessgranted=False
i = 0 #1
while accessgranted==False:
username=input("username:")
password=input("account no:")
if username==bankdetails[i] and password==bankdetails[i+1]:
accessgranted=True
print("Access Granted") #2
break
else:
accessgranted=False
print("Sorry, wrong credentials") #3
i += 2
1)它将是文件
中包含的数据总长度的开始2)如果用户名和密码正确,则打印&#34;访问授权&#34;在中断之前,它将不会被打印,因为执行将在中断后移出循环
3)打印错误的凭据&#34;如果数据没有匹配并转移到下一次迭代并给出另一次机会
答案 2 :(得分:0)
如何(未经测试):
def strip_split_read_from_file():
bankdetails=[]
with open("bankdetails.txt","r") as f:
for line in f:
line = line.rstrip()
pair = line.split(",") # 1
assert(len(pair) == 2) # 2
bankdetails.append(pair) # 3
accessgranted=False
while accessgranted==False:
username=input("username:")
password=input("account no:")
for pair in bankdetails: # 4
if username==pair[0] and password==pair[1]: # 5
accessgranted=True
break
else:
accessgranted=False
if accessgranted==True:
print("Access Granted")
else:
print("Sorry, wrong credentials")
注意:
标记为1-3的行稍微改变了存储(用户名,帐号)对的布局。索引0,2,4,6,...表示用户名和1,3,5,7,...代表帐号,而不是存储为“平面”列表,而是现在有两个维度。现在,bankdetails
是一个包含2元素元组的列表,其中第一个元素是用户名,第二个元素是帐号。这与文件的布局非常相似。
之前,您的列表看起来像:
[username1, account1, username2, account2, username3, ...]
现在它看起来像:
[
(username1, account1),
(username2, account2),
(username3, account3),
...
]
第2行只对数据执行(非常基本的)健全性检查。
第4行只是将循环变量重命名为pair
,以更好地表示将分配给该变量的内容,一个bankdetails条目 - 一对。 (i
通常保留用于最小范围的整数循环变量)
第5行使用pair
并访问该对中的各个元素 - pair[0]
获取第一个,用户名和pair[1]
获取第二个/最后一个,即帐号。
这一切都改变了。最后,您可能会考虑制作一个Account
类,您可以为每个帐户实例化,并且具有username
和account_number
成员属性。您也可以使用命名元组来实现类似目的。
此外,您可以稍微清理一下程序的流程,或许类似于(再次,未经测试):
def strip_split_read_from_file():
bankdetails=[]
with open("bankdetails.txt","r") as f:
for line in f:
line = line.rstrip()
pair = line.split(",") # 1
assert(len(pair) == 2) # 2
bankdetails.append(pair) # 3
return bankdetails
def evaluate_login(bankdetails, username, password):
for pair in bankdetails: # 4
if username==pair[0] and password==pair[1]: # 5
return True
return False
# Read file containing account info
bankdetails = strip_split_read_from_file()
# Prompt user for login
username=input("username: ")
password=input("account no: ")
# Test user input
accessgranted = evaluate_login(bankdetails, username, password):
# Show login result
if accessgranted==True:
print("Access Granted")
else:
print("Sorry, wrong credentials")
答案 3 :(得分:0)
我建议您使用以下代码:
import csv
with open('bankdetails.txt', 'r') as file:
reader = csv.reader(file)
bankdetails = [row for row in reader]
这将为您提供客户列表列表:
[['customer1', '1'], ['customer2', '2'], ['customer3', '3'], ['customer4', '4'], ['customer5', '5']]
现在,你可以更容易地改进它:
for customer in bankdetails:
customer[0] would be your customer
customer[1] would be your digit