Home > Blockchain >  What Happens when Combining the 'in' Operator with the 'for in' Operator in Pyth
What Happens when Combining the 'in' Operator with the 'for in' Operator in Pyth

Time:11-24

When looking for a secure random password generator in Python I came across this script:

# necessary imports
import secrets
import string

# define the alphabet
letters = string.ascii_letters
digits = string.digits
special_chars = string.punctuation

alphabet = letters   digits   special_chars

# fix password length
pwd_length = 12

# generate a password string
pwd = ''
for i in range(pwd_length):
  pwd  = ''.join(secrets.choice(alphabet))

print(pwd)

# generate password meeting constraints
while True:
  pwd = ''
  for i in range(pwd_length):
    pwd  = ''.join(secrets.choice(alphabet))

  if (any(char in special_chars for char in pwd) and 
      sum(char in digits for char in pwd)>=2):
          break
print(pwd)

Source: How to Create a Random Password Generator in Python - Geekflare There is one thing that is unclear to me in the final "if" statement, which checks if the generated password meets certain constraints.

The expression is:

char in special_chars for char in pwd

I understand, that "in" can either check if something is part of an iterable or be part of the "for in" statement that generates a loop from an iterable.

But what I do not understand is how these both are interacting here. To me it looks as if "char in special_chars" checks if the second "char", defined in "for char in pwd", is part of special_chars.

But: how does the first "char" gets defined before the "char" in "for in" gets defined? I always thought that a variable could not be accessed before it gets defined. This example looks to me as if Python behaves differently. Could anybody explain this to me?

CodePudding user response:

This is known as a list comprehension.

A very simple example of this is:

[i for i in range(5)] => [0, 1, 2, 3, 4]

Now, breaking down your example.

The second half of the list comprehension for char in pwd is looping through every character in the password.

Now the first part char in special_chars is giving a True or False value depending on whether the current charcter in the for char in pwd loop is a special character or not.

I've tried to show a basic example below

pwd = 'qw@rt&'
char in special_chars for char in pwd => [False, False, True, False, False, True]

The any() statement is then checking this created list to see if there is at least one True value

CodePudding user response:

Thank's to @matszwecja I can explain it myself:

The whole construct is a so called generator expression: 6. Expressions -- Python 3.11.0 documentation

"Variables used in the generator expression are evaluated lazily when the next() method is called for the generator object (in the same fashion as normal generators)."

This explains to me how the first 'char' knows about the second 'char' defined in the for-loop.

  • Related