Enigmatic
Enigmatic

Reputation: 4148

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

Upvotes: 1

Views: 66

Answers (2)

mhawke
mhawke

Reputation: 87074

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.

Upvotes: 1

Uriel
Uriel

Reputation: 16184

When you cast a list to a string back and forth, the result wouldn't be the original string. It would be a list containing the characters of the representation of the original string.

>>> a = [1, 2, 3]
>>> b = str(a)
>>> c = list(b)
>>> c
['[', '1', ',', ' ', '2', ',', ' ', '3', ']']

Don't do such castings, and if you have to, use ','.join(map(str, a)) to cast to string, and list(map(int, b.split(','))) to cast to list back.

Upvotes: 1

Related Questions