0

i'm very new to python so please forgive me if my error is blatantly obvious.

The issue I am having is with line 15. I am struggling to check if the input value is NOT in the list "list"

All values currently entered (in and not in the list "list") will return the response "srry".

I know line 15 is at fault because if I create a separate list with no nested lists for the countries: England, French and Mandarin to be called just for line 15, the appropriate response based on input is printed as expected.

Any help would be highly appreciative.

#input
lang = str(input("Please Type in the Language you speak and press enter 
('make sure you use a capital letter')"))
#list of countries
list = [["English", "english"], ["French", "french"], ["Mandarin", 
"mandarin"]]

#list of responses
lls = ["Hello,", "Bonjour,", "Ni Hao"]

srry = "Sorry, but I don't speak that"
welcmsg = "Welcome to Coventry"

# check if input is not in list
if str(lang) not in list:    
  print(srry)

#provide appropriate response based on input
elif str(lang) in list[0]:
  print(lls[0] + " " + welcmsg)  
elif str(lang) in list[1]: 
  print(lls[1] + " " +welcmsg) 
elif str(lang) in list[2]: 
  print(lls[2])
J.Allen
  • 3
  • 2
  • btw, Avoid naming variables with same names as `built-in` python keywords, e.g. [`list`](https://docs.python.org/3/library/functions.html#func-list) is a python keyword and shadowing it with your variable name can have unexpected behavior, instead consider using a different variable name like `mylist`, etc. Not sure if it is related to your problem, but may help. – chickity china chinese chicken Oct 11 '17 at 00:36

1 Answers1

0

TLDR; change line 15 to search the list-of-lists:

# check if input is not in list
if lang not in [item for sublist in mylist for item in sublist]:    
  print(srry)

Details:
The problem is that "list" is a nested-list (a list-of-lists), and so when we check if the input value is not in the list, we're checking if the value is only in the outer-most level of the list, which are still lists.

Consider the following:

list of lists:

>>> mylist = [['a', 'b'], ['x', 'y']]
>>> 'x' in mylist
False

vs. a single-level, flat list:

>>> mylist = ['a', 'b', 'x', 'y']
>>> 'x' in mylist
True

To fix it we can either convert the initial list-of-lists to one "flat" list (single-level), or we'll need to search each sub-list within the "list".

Keeping the code as close to the original and only changing the line 15 list search:

# check if input is not in list
if lang not in [item for sublist in mylist for item in sublist]:    
  print(srry)

Also, as mentioned in the comment - consider using a different variable name for the "list" that doesn't overwrite the built-in keyword list to prevent unexpected behavior. Here I've used mylist for the "list" name.


Another thing you might consider is using str.lower() when taking user input:

>>> mylist = ["english", "french", "mandarin"]
>>> lang = str(input("language? ").lower())
language? French
>>> lang in mylist
True

The user can still use a capital-letter for the input, but it makes the input validation a bit easier to check with fewer strings to check. Just a side-tip.

Hope this helps!

  • Thank you! Your alternative makes far more sense. Just a thought that popped into my head, but would it be possible to condense it further by using an associative array? myArray{"english": "Hello", "french": "Bonjour", "mandarin":"Ni Hao"} – J.Allen Oct 11 '17 at 15:13
  • Yes that a very good idea, make sure you assign it with an `=` sign, so you have `myarray = {"english": "Hello", "french": "Bonjour", "mandarin":"Ni Hao"}`, then the output becomes just one line of code `print (myarray[lang] + " " + welcmsg)` – chickity china chinese chicken Oct 11 '17 at 16:43