Search code examples
pythonlistpython-3.xstring-comparisonlist-comparison

Why am I receiving an error when trying to compare two lists?


I am trying to compare two lists on line #12 and return matches found.

The lists contain one user selected number (un) and one of which have been randomly generated (rn).

For example, [['1', '5', '3', '7']] and [['9', '6', '3', '2']] would return [3].

I am fairly new to python and was using the solution found HERE, but am yet to have success with my code.

import random
import re

rn = []
un = []

Numbers = range(1000,9999)
RandomNumber = random.choice(Numbers)
RandomNumber = str(RandomNumber)

def check():
    x = set(rn) & set(un) #12
    print (x)

def numsys():
    b = list(RandomNumber)
    rn.append(b)
    print(rn)
    print(un)
    check()


def numval():
    while True:
        UserNum = (input("Please enter a 4 digit number: "))
        if re.match("^[0-9]{4,4}$", UserNum):
            a = list(UserNum)
            un.append(a)
            numsys()
            break        
numval()

Solution

  • Rather than using lists to pass the data around, use function parameters.

    import random
    import re
    
    def check(random_number, user_number):
        print('random_number {}, user_number {}'.format(random_number, user_number))
        x = set(random_number).intersection(user_number)
        print(x)
    
    def numval():
        random_num = str(random.choice(range(1000, 9999)))
        while True:
            user_num = (input("Please enter a 4 digit number: "))
            if re.match("^[0-9]{4,4}$", user_num):
                check(random_num, user_num)
                break
    
    numval()
    

    This avoids accessing global variables within the functions and is generally more readable. Doing this I was able to remove function numsys() because all it was doing was to unnecessarily fiddle with the global variables in order to make their values accessible in function check().

    One simplification was to keep the random and user numbers as strings. set() can be called on a string without requiring that it be first converted to a list. And only one of the strings needs to be explicitly converted to a set if you use set.intersection() instead of the & operator.

    I also took the liberty of renaming the variables to conform with the PEP8 style guide.