Home > OS >  How to accept input from an enumerated list in Python?
How to accept input from an enumerated list in Python?

Time:10-02

So I have a list that I want to number using enumerate(), then have the user choose an item from the list using the corresponding number. Is there a way to do this?

(This is broken code but hopefully, you get an idea of what I want to do)

print("Which house do you want to sell")
for number,address in enumerate(market['addresses'], 1):
    print(number, '->', address)
userSell = input("> ")
if userSell in enumerate(market['addresses']):
    print(f"Sold {address}")
else:
    print("Address not found...")

CodePudding user response:

IIUC, you can use the inputted number to index your list directly:

print("Which house do you want to sell")
for number,address in enumerate(market['addresses'], 1):
    print(number, '->', address)
userSell = int(input("> "))-1 # you might need a loop/check here to ask again on incorrect input

try:
    # assuming market['addresses'] is a list
    print(f"Sold {market['addresses'][userSell]}")
except IndexError:
    print("Address not found...")

CodePudding user response:

Try changing

if userSell in enumerate(market['addresses']):

to

if userSell in range(1, len(market['addresses'])):

This will loop through the values in the range (indexes) of the addresses at the end.

CodePudding user response:

To make the original code work as intended, I believe you also need to convert the user input to int type and subtract 1 because you specified start=1 when printing the options.

market= {'addresses': ["This Street", "That Street"]}
print("Which house do you want to sell")
for number,address in enumerate(market['addresses'], 1):
    print(number, '->', address)
userSell = int(input("> ")) - 1
if userSell in range(len(market['addresses'])):
    print(f"Sold {address}")
else:
    print("Address not found...")

Having to subtract 1 to make the input match the options does not feel very robust as you will have to remember to adjust the index any time you look up elements in the list later in the code. It is a good idea to store the numbered options and reference the same object later. Converting to a dict makes the code nice and readable and understandable.

market= {'addresses': ["This Street", "That Street"]}
numbered_options = dict(enumerate(market['addresses'], 1))
print("Which house do you want to sell")
for number,address in numbered_options.items():
    print(number, '->', address)
userSell = int(input("> "))
if userSell in numbered_options:
    print(f"Sold {numbered_options[userSell]}")
else:
    print("Address not found...")

What I would really recommend, though, is using one of the many pre-built libraries for displaying lists of options and getting choices from users in the command line. You can choose from the ones mentioned in this thread and consult library documentation to implement them. No need to redo something somebody else has already done for you.

CodePudding user response:

It's always a good idea to validate user input - especially when you're expecting numeric values.

If you do that in this case there's no need to lookup the address after user input because you will already have validated it.

market = {'addresses': ['1 Main Road', '2 Long Street', '100 Pall Mall']}
addresses = market['addresses']
print("Which house do you want to sell?")
for number, address in enumerate(addresses, 1):
    print(number, '->', address)
while True:
    try:
        userSell = int(input("> "))
        if 0 < userSell <= len(addresses):
            break
        raise ValueError('Selection out of range')
    except ValueError as ve:
        print(ve)
print(f'Sold {addresses[userSell-1]}')

Output:

Which house do you want to sell?
1 -> 1 Main Road
2 -> 2 Long Street
3 -> 100 Pall Mall
> 2
Sold 2 Long Street

With invalid user input:

Which house do you want to sell?
1 -> 1 Main Road
2 -> 2 Long Street
3 -> 100 Pall Mall
> 0
Selection out of range
> 4
Selection out of range
> foo
invalid literal for int() with base 10: 'foo'
> 1
Sold 1 Main Road
  • Related