views:

54

answers:

2

I would like to get user input to refer to some list in my code. I think it's called namespace? So, what would I have to do to this code for me to print whatever the user inputs, supposing they input 'list1' or 'list2'?

list1 = ['cat', 'dog', 'juice']
list2 = ['skunk', 'bats', 'pogo stick']

x = raw_input('which list would you like me to print?')

I plan to have many such lists, so a series of if...then statements seems unruly.

+5  A: 

In the cases I can think of right now it would probably be better to have a dictionary containing what you want the user to be able to reference, for example:

my_dict = {
    'list1': ['cat', 'dog', 'juice']
    'list2': ['skunk', 'bats', 'pogo stick']
}

key = raw_input('which list would you like me to print?')

print my_dict[key]

In fact, you can take advantage of the built-in globals(), like this:

list1 = ['cat', 'dog', 'juice']
list2 = ['skunk', 'bats', 'pogo stick']
x = raw_input()

print globals()[x]
Flávio Amieiro
+1 I agree completely. Note that the `globals()` function will give you a dictionary that contains all global variables, but it's generally preferable to use your own dictionary when you plan to be using it like this.
David Zaslavsky
@David I was editing my post to add information about globals() when you posted the comment, but I agree that it's probably a better idea to have your own dictionary.
Flávio Amieiro
Exposing internal variables is exceedingly questionable from a security standpoint. If this code is anywhere near a security boundary (runs suid, is used for a web application, etc), the globals() approach is a horrifyingly bad plan.
Slartibartfast
@everyone, thanks for the responses. The reason I did not wanted to use lists (instead of dictionaries) is because some of these lists should have identical content. Do you suggest a workaround for this? I want list1 and list2 to potentially be identical and yet have the user help determine which to print.
somefreakingguy
@slartibartfast I couldn't agree more. Using globals() is almost always a bad idea, *specially* if it involves user input. Anyways, I was just trying to find a way to answer (technically) somefreakingguy's question, while showing that if you have a limited set of choices it's probably better to build your own dictionary.
Flávio Amieiro
+2  A: 

The general idea of using a dict is good, but the best specific implementation is probably something like:

def pick_one(prompt, **kwds):
  while True:
    x = raw_input(prompt)
    if x in kwds:
      return kwds[x]
    else:
      print 'Please choose one of: ',
      for k in sorted(kwds): print k,
      print

To be used, e.g., as:

print pick_one('which list would you like me to print?',
    list1 = ['cat', 'dog', 'juice']
    list2 = ['skunk', 'bats', 'pogo stick'])

The point is that, when you're asking the user to select one among a limited number of possibilities, you'll always want to check that the choice was one of them (it is after all easy to mis-spell, etc), and, if not, prompt accurately (giving the list of available choices) and give the user another chance.

All sorts of refinements (have a maximum number of attempts, for example, after which you decide the user just can't type and pick one at random;-) are left as (not too hard but not too interesting either;-) exercises for the reader.

Alex Martelli