简体   繁体   English

在两个不同的列表中查找相同索引号以比较值的最有效方法

[英]most efficient way to look up the same index number in two different lists to compare values

I have the following code and it is the login feature that I need help with. 我有以下代码,这是我需要帮助的登录功能 I have two lists - usernames and passwords . 我有两个列表 - 用户名和密码 The login feature asks the user to enter a username and password. 登录功能要求用户输入用户名和密码。 If the entered username is in the usernames list AND corresponds to the same index number in the passwords list, THEN, return "Access granted", else "Denied". 如果输入的用户名在用户名列表中并且对应于密码列表中的相同索引号,则返回“已授予访问权限”,否则返回“拒绝”。

I'd be interested in two things for teaching purposes: a) a simple fix to the problem using the two lists as specified. 为了教学目的,我会对两件事感兴趣:a)使用指定的两个列表对问题进行简单修复。 b) suggestions as to the best way to solve this problem. b)有关解决此问题的最佳方法的建议。 (eg dictionaries, 2darrays, or anything else). (例如,字典,2darrays或其他任何东西)。

The issue is needing to iterate through both lists simulatenously and look up the same corresponding index number. 问题是需要模拟地遍历两个列表并查找相同的对应索引号。

Example: 例:

username1 and pass1 = access granted but username1 and pass2 =access denied username1和pass1 =授予访问权限, username1和pass2 =拒绝访问

CODE: 码:

usernames=["user1","user2","user3"]
passwords=["pass1","pass2","pass3"]

def main():
   mainmenu()


def mainmenu():
   print("****MAIN MENU****")
   print("=======Press L to login :")
   print("=======Press R to register :")
   choice1=input()
   if choice1=="L" or choice1=="l":
      login()
   elif choice1=="R" or choice1=="r":
      register()
   else:
      print("please make a valid selection")

def login():
   print("*****LOGIN SCREEN******")
   username=input("Username: ")
   password=input("Password: ")
   if username in usernames and password in passwords:
      print("yes")
   else:
      print("denied")


def register():
   print("*****REGISTRATION****")
   username=input("Enter a username:")
   password=input("Enter a password:")
   usernames.append(username)
   passwords.append(password)
   answer=input("Do you want to make another registration?")
   if answer=="y":
      register()
   else:
      registration_details()

def registration_details():
   print(usernames)
   print(passwords)

main()

Note: I am aware that storing the lists in a 2d array would be an obvious solution/suggestion, but this fix is necessary for pedagogical reasons - ie students have not yet covered arrays at all. 注意:我知道将列表存储在2d数组中将是一个明显的解决方案/建议,但是出于教学原因,此修复是必需的-即学生尚未完全覆盖数组。 Looking at simple solutions first, but also stackoverflow users would benefit from suggestions to alternate/more efficient methods to solve this problem as well. 首先查看简单的解决方案,然后堆栈溢出用户也将从采用替代/更有效方法来解决该问题的建议中受益。

UPDATE: 更新:

As someone has commented below ...I thought I'd clarify. 正如下面有人提到的...我想澄清一下。 I'm aware that what is needed is to get at the index numbers of the said values in the lists. 我知道,需要获取列表中所述值的索引号。 My question is - what is the best solution, or some of the solutions. 我的问题是-什么是最佳解决方案,或者是某些解决方案。 Enumerate. 枚举。 zip. 压缩。 simply using a for loop? 只是使用for循环? It is quite difficult to know how to start in python as there is not just one way ...any comments as to which would be the most idiomatic (pythonic) would also be useful. 知道如何从python开始是非常困难的,因为不仅有一种方法...关于哪一种注释是最惯用的(pythonic)注释也将很有用。

BEST ANSWER: 最佳答案:

This is possibly the best answer, presented below by Damian Lattenero The indentation, a common error, below is off. 这可能是最好的答案,以下由Damian Lattenero提出。缩进(一种常见的错误)已关闭。 Is it possible to also just make a quick comment on why? 是否可以对原因进行快速评论? How to fix it? 如何解决?

def login():
   print("*****LOGIN SCREEN******")
   username=input("Username: ")
   password=input("Password: ")
   for ind, user in enumerate(usernames):
     if username == user and passwords[ind] == password:
       print("correct login")
     else:
       print("invalid username or password")

OUTPUT 输出值

*****LOGIN SCREEN******
Username: user3
Password: pass3
invalid username or password
invalid username or password
correct login
>>> 

If you want to teach python foundations... 如果您想教python基础...

zip(usernames, passwords)

leads to 导致

dict(zip(usernames, passwords))

but you could also do... 但是你也可以做...

for (idx, username) in enumerate(usernames):
   valid_password = passwords[idx]

I suggest to use dictionary in this case, look I'll show you how: 我建议在这种情况下使用字典,看看我将向您展示如何:

users_pass = {"user1" : "pass1", "user2":"pass2", "user3":"pass3"}

def login():
   print("*****LOGIN SCREEN******")
   username=input("Username: ")
   password=input("Password: ")
   if username not in users_pass:
      print("The user doesnt exist")
   elif users_pass[username] == password:
      print("password ok")


def register():
   print("*****REGISTRATION****")
   username=input("Enter a username:")
   password=input("Enter a password:")
   users_pass[username] = password
   answer=input("Do you want to make another registration?")
   if answer=="y":
      register()
   else:
      registration_details()

if you only want to use lists: 如果您只想使用列表:

usernames=["user1","user2","user3"]
passwords=["pass1","pass2","pass3"]

def login():
  print("*****LOGIN SCREEN******")
  username=input("Username: ")
  password=input("Password: ")
  for index_of_current_user, current_user in enumerate(usernames): #enumerate allows to you to go throw the list and gives to you the current element, and the index of the current element
    if username == current_user and passwords[index_of_current_user] == password: #since the two list are linked, you can use the index of the user to get the password in the passwords list
      print("correct login")
    else:
      print("invalid username or password")

def register():
  print("*****REGISTRATION****")
  username=input("Enter a username:")
  password=input("Enter a password:")
  users_pass[username] = password
  answer=input("Do you want to make another registration?")
  if answer=="y":
    register()
  else:
    registration_details()

An easy fix to your code, but not recommended, is by using zip() . 使用zip()可以轻松解决您的代码,但不建议这样做。

You need to replace this if statement: 您需要替换此if语句:

if username in usernames and password in passwords:
    print("yes")
else:
    print("denied")

by: 通过:

if (username, password) in zip(usernames, passwords):
    print("yes")
else:
    print("denied")

However, you can use a dict where you store your unique usernames ans password and then check if the username is in this current dict then check if the password is correct or not. 但是,您可以使用存储您唯一的用户名和密码的dict ,然后检查用户名是否在当前字典中,然后检查密码是否正确。

Here are a couple more methods, neither of which I'd particularly recommend, but most other decent ways have been covered in previous answers. 这里有另外两种方法,我都不特别推荐,但以前的答案中已经介绍了大多数其他不错的方法。

These methods might be better for teaching some general programming basics, but not necessarily for teaching Python... 这些方法可能适合于教授一些通用的编程基础知识,但不一定适合于教授Python ...

# Both methods assume usernames are unique

usernames=["user1","user2","user3"]
passwords=["pass1","pass2","pass3"]

username = "user2"
password = "pass2"


# Method 1, with try-catch

try:
  idx = usernames.index(username)
except ValueError:
  idx = None

if idx is not None and password == passwords[idx]:
  print "yes1"
else:
  print "denied1"


# Method 2, no try-catch

idx = None
if username in usernames:
  idx = usernames.index(username)

  if password != passwords[idx]:
    idx = None

if idx is not None:
  print "yes2"
else:
  print "denied2"

This is a great scenario for the zip and enumerate functions. 对于zipenumerate函数,这是一个很好的方案。 If I read your question correctly, you want to 如果我正确阅读了您的问题,您想

  • Iterate across both usernames and passwords simultaneously (zip) 同时遍历用户名和密码(zip)
  • Keep track of index (enumerate) 跟踪索引(枚举)

Given your two lists (usernames and passwords), you will want to do the following 给定两个列表(用户名和密码),您将需要执行以下操作

for i, (username, password) in enumerate(zip(usernames, passwords)):
    print(i, username, password)

Here's a description on what's going on. 这是对正在发生的事情的描述。

1) The zip function is taking your usernames and passwords lists and creates a new list (an iterable zip object to be precise) where each username and password is appropriately paired. 1) zip函数获取您的usernamespasswords列表,并创建一个新列表(准确地说是一个可迭代的zip对象),其中每个用户名和密码都已正确配对。

>>> zip(usernames, passwords)
<zip object at 0x_________> # hmm, cant see the contents

>>> list(zip(usernames, passwords))
[("user1", "pass1"), ("user2", "pass2"), ("user3","pass3")]

2) The enumerate function is taking a list, and creating a new list (actually an iterable enumerate object) where each item is now paired with an index. 2) enumerate函数获取一个列表,并创建一个新列表(实际上是一个可迭代的枚举对象),其中每个项目现在都与一个索引配对。

>>> enumerate(usernames)
<enumerate object 0x_________> # Lets make this printable

>>> list(enumerate(usernames))
[(0, "user1"), (1, "user2"), (2, "user3")]

3) When we combine these, we get the following. 3)当我们结合这些,我们得到以下。

>>> list(enumerate(zip(usernames, passwords))
[(0, ("user1", "pass1")), (1, ("user2", "pass2")), (2, ("user3", "pass3"))]

This gives us a list where each element is of the form (index, (username, password)) . 这为我们提供了一个列表,其中每个元素的形式为(index, (username, password)) Which is super easy to use with a loop! 使用循环超级简单!

4) Setup your loop with the above! 4)用上面的设置循环!

for i, (username, password) in enumerate(zip(usernames, passwords)):
    # Freely use i, username and password! 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM