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

时间:2017-06-29 20:09:39

标签: python list loops simultaneous

我有以下代码,我需要帮助的是登录功能。我有两个列表 - 用户名和密码。登录功能要求用户输入用户名和密码。如果输入的用户名在用户名列表中并且对应于密码列表中的相同索引号,则返回"访问被授予",否则"拒绝"。

我对教学目的感兴趣: a)使用指定的两个列表对问题进行简单修复。 b)关于解决这个问题的最佳方法的建议。 (例如字典,2个数组或其他任何内容)。

问题是需要同时迭代这两个列表并查找相同的相应索引号。

示例:

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

注意:我知道将列表存储在二维数组中将是一个明显的解决方案/建议,但出于教学原因这个修复是必要的 - 即学生根本没有覆盖数组。首先看一下简单的解决方案,但stackoverflow用户也会受益于替代/更有效的方法来解决这个问题的建议。

更新:

正如有人在下面评论过......我以为我会澄清一下。我知道所需要的是获取列表中所述值的索引号。我的问题是 - 什么是最好的解决方案,或者一些解决方案。枚举。压缩。只是使用for循环?很难知道如何在python中启动,因为不只有一种方式...任何关于哪种最惯用(pythonic)的评论也会有用。

最佳答案:

这可能是Damian Lattenero在下面提出的最佳答案 下面的缩进是一个常见的错误。是否有可能只是快速评论为什么?怎么解决?

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

输出

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

5 个答案:

答案 0 :(得分:4)

如果你想教python基础......

zip(usernames, passwords)

导致

dict(zip(usernames, passwords))

但你也可以......

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

答案 1 :(得分:1)

我建议在这种情况下使用字典,看看我会告诉你如何:

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

如果您只想使用列表:

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

答案 2 :(得分:1)

使用zip()

可以轻松修复代码,但不建议使用

您需要替换此if语句:

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

由:

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

但是,您可以使用dict存储唯一用户名和密码,然后检查用户名是否在当前dict中,然后检查密码是否正确。

答案 3 :(得分:1)

以下是一些方法,我都不特别推荐这些方法,但大多数其他方法都已在以前的答案中介绍过。

这些方法可能更适合教授一些通用编程基础知识,但不一定用于教授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"

答案 4 :(得分:1)

这是zipenumerate功能的绝佳方案。如果我正确地读了你的问题,你想要

  • 同时迭代用户名和密码(zip)
  • 跟踪索引(枚举)

鉴于您的两个列表(用户名和密码),您需要执行以下操作

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

以下是对正在进行的内容的描述。

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)enumerate函数正在获取一个列表,并创建一个新列表(实际上是一个可迭代的枚举对象),其中每个项目现在都与索引配对。

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

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

3)当我们将这些结合起来时,我们得到以下结论。

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

这为我们提供了一个列表,其中每个元素的格式为(index, (username, password))。这是一个非常容易使用循环!

4)用上面的方法设置你的循环!

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