Search code examples
pythonbitwise-operatorslogical-operators

TypeError when trying to do a Boolean AND


I'm trying to learn python but I got stuck on some practice code. I want to check to see if two of the three items I am putting into a list named guesses are in another list named favorite while checking to see if the third item I am putting into the list guesses is not in the other list favorite.

games = ['CS:GO', 'MK11', 'Black Ops 3', 'League of Legends', 'Osu!', 'Injustice 2', 'Dont Starve', 'Super Smash Brothers: Ultimate', 'God of War', 'Kingdom Hearts 3', 'Red Dead Redemption 2', 'Spider-Man', ]

favorite = ['God of War', 'CS:GO', 'Spider-Man']
guesses = ['', '', '']

print('I like ' + str(len(games) + 1) + ' games and here there are:' + str(games[:8]) + '\n' + str(games[9:]))
print('Can you guess whats are my favorite three games out of my list?')
guesses[0] = input()
print('Whats game number 2?')
guesses[1] = input()
print('Whats game number 3?')
guesses[2] = input()

# if all(x in favorite for x in guesses):
#     print('Yes! Those are my three favorite games!')

if guesses[0] in favorite & guesses[1] in favorite & guesses[2] not in favorite:
    print('Sorry, ' + str(guesses[0]) + ' & ' + str(guesses[1]) + ' are two of my favorite games but unfortunately ' + str(guesses[2]) + ' is not.')

My issue is that I thought my if statement above would work, may someone please explain why I am getting this TypeError below:

  line 18, in <module>
    if guesses[0] in favorite & guesses[1] in favorite & guesses[2] not in favorite:
TypeError: unsupported operand type(s) for &: 'list' and 'str'

I also understand that the all function works in this case to see if all of the items if both lists are equal but I want to know if two of the three items are equal while the third isn't.

Thank you.


Solution

  • You are use a single ampersand, not and in your final if statement.

    if guesses[0] in favorite and guesses[1] in favorite and guesses[2] not in favorite:
        print('Sorry, ' + str(guesses[0]) + ' & ' + str(guesses[1]) + ' are two of my favorite games but unfortunately ' + str(guesses[2]) + ' is not.')
    

    A single ampersand means bitwise and which is done on binary types, and not boolean and which is what you require.


    As an aside (if this matters to your program), it is worth noting that this only checks one permutation of your guesses list (i.e. what if guesses[0] was not in favourites instead of guesses[2]?)

    Although probably not the most efficient or elegant, you could achieve this with a map and sum:

    # Turns each element of guesses into 1 if it's in favourites or 0 if not.
    in_favourites = map(lambda x: 1 if x in favourites else 0, guesses)
    # Sum the list of 1's and 0's
    number_in_favourites = sum(in_favourites)
    # Do your check (you could do number_in_favourites >= 2)
    if number_in_favourites == 2:
        print("Woopee!")
    
    # Or more concisely:
    if sum(map(lambda x: x in favourites, guesses)) == 2:
        print("Woopee!")
    

    (Disclaimer, I'm writing this code purely in a browser so I haven't tested it, but it should be roughly like that!)