使用for循环错误地检查列表中的字段 [英] Incorrect checking of fields in list using a for loop

查看:181
本文介绍了使用for循环错误地检查列表中的字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码,试图将文件内容读入一个列表(这个工作),然后显示一个接受的消息,如果银行的详细信息(用户和相应的号码)匹配。例如,

如果输入用户名:customer1和account_number:1 >>授予访问权限,以便文件中的每个客户和帐号。



文件详细信息

 客户1,1 
客户2,2
客户3,3
客户4,4
customer5,5

代码

$

  def strip_split_read_from_file():
bankdetails = []
with open(bankdetails.txt,r)as f:
用于f:
line = line.rstrip()#r strip从字符串右边删除新的行字符
split_line = line.split(,)
for split_line:
bankdetails.append(field)
$ b accessgranted = False
accessgranted == False:
username = input(username: )
密码=输入(帐户号码)

在银行帐户中:
如果用户名== bankdetails [i]和密码== bankdetails [i + 1 ]:
accessgranted = True
break
else:
accessgranted = False

$ b如果accessgranted == True:
print(Access Granted )
其他:
print(抱歉,错误的凭据)

错误

  if username == bankdetails [i] and password == bankdetails [i + 1] :
TypeError:列表索引必须是整数,而不是str

对于答案和教学/学习的目的我想下面的


  1. 更正使用现有的提供的代码清楚地解释错误


  2. 有关以最有效的方法实现相同目标的替代方法的建议



>将成为银行的每一个细节,而不是它的意愿成为元素的位置。如果你想要它成为头寸,你必须为len(bankdetails)中的$ ,因为 len()是获取数据结构长度的函数。但是,由于每次都需要两个字段,所以我建议使用一个while结构来完成,如下所示:

  total = len(bankdetails) -  1 
i = 0
while I<总数:
如果用户名== bankdetails [i]和密码== bankdetails [i + 1]:
accessgranted = True
break
else:
accessgranted = False但是,如果列表中有许多条目,则迭代他们都可以花很多时间。为了避免这种情况,使用字典是最好的选择:检查一个项目是否快得多,你不需要迭代来找到与它相关的值。


如果你不知道字典是如何工作的,它就像列表一样工作,除非它们没有被排序,而你寻找一个项目的方式是检查与关键字相关联的值。让我们更清楚。在你的文件中,你有:

  customer1,1 
customer2,2
customer3,3
customer4,4
customer5,5

将它们添加到字典中的方法be:

  bankdetails = {}#注意,它们被初始化为{} 
,并打开(bankdetails。 f:
为f:
line = line.rstrip()#r strip从字符串右边删除新的行字符
split_line = line.split(,)
username = split_line [0]
password = split_line [1]
bankdetails [username] = password

这样bankdetails将包含 {'customer1':'1','customer2':'2',... }



而且,要查找用户及其密码,您必须这样做:

 用户名=输入(用户名:)
密码=输入(帐号:)
如果用户名在bankdetails:
如果bankdetails [用户名] ==密码:
accessgranted = True
break
else:
accessgranted = False

这样可以完成你想要的功能,但是如果你有很多条目,速度会更快。


I have the following code that seeks to read the file contents into a list (this bit works) and then display a message of acceptance, IF the bank details (user and corresponding number) matches.

e.g. if username: customer1 and account_number:1 is entered >> Access Granted and so on for each customer and account number in the file.

File details

customer1,1
customer2,2
customer3,3
customer4,4
customer5,5

Code

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")

Error

 if username==bankdetails[i] and password==bankdetails[i+1]:
TypeError: list indices must be integers, not str

For an answer, and teaching/learning purposes I would like the following

  1. Correction with clear explanation of the error using the existing, provided code

  2. Suggestions as to alternative ways to achieve the same objective in the most efficient method possible

解决方案

for i in bankdetails: means that i will become every element in bankdetails, not that it will become the position of the element. If you want it to become the position, you must do for i in len(bankdetails), because len() is the function to get the length of a data structure. However, since you take two fields every time, I'd recommend to do it with a while structure, like this:

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

However, if you have lots of entries in your list, iterating over all of them can take a lot of time. To avoid this, using a dictionary is the best option: checking if an item is in it is a lot faster, and you don't need to iterate to find the value associated with it.

If you don't know how dictionaries work, it kinda works like a list, except they're not ordered, and the way you look for an item is checking the value associated to a key. Let's be more clear. In your file, you have:

customer1,1
customer2,2
customer3,3
customer4,4
customer5,5

The way to add them in a dictionary would be:

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

This way, bankdetails will contain {'customer1': '1', 'customer2': '2', ... }

And, to look for the user and its password, you'd have to do this:

username=input("username:")
password=input("account no:")
if username in bankdetails:
    if bankdetails[username]==password:
       accessgranted=True
       break
    else:
        accessgranted=False

This will do exactly what you wanted, but much faster if you had lots of entries.

这篇关于使用for循环错误地检查列表中的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆