Skip to main content

How to Get User Input to Select an Option from a List in Python

Interacting with users often involves presenting them with a set of choices and asking them to select one. Whether it's choosing an item from a menu, selecting a configuration option, or answering a multiple-choice question, Python provides ways to handle this using the input() function and control flow structures.

This guide demonstrates common techniques for prompting users to select an option from a list by name or by number, along with using the inquirer library for more interactive menus.

The Goal: Selecting from Options

We want to display a list of predefined options to the user and repeatedly ask for their choice until they provide a valid selection corresponding to one of those options.

Method 1: Prompting with Numbered Options

This common pattern displays the options with numbers and allows the user to select either by typing the number or the option's name.

Building the Prompt Message

Use enumerate() and an f-string to dynamically create a message listing the options with 1-based numbers.

options = ['python', 'javascript', 'typescript', 'go']
input_message = "Pick a language:\n" # Start with a title

# enumerate starts index at 0, so add 1 for display
for index, item in enumerate(options):
input_message += f'{index + 1}) {item}\n' # Add each option

input_message += 'Your choice (enter number or name): ' # Final prompt part

print("--- Generated Prompt ---")
print(input_message)
print("-----------------------")
# Output:
# --- Generated Prompt ---
# Pick a language:
# 1) python
# 2) javascript
# 3) typescript
# 4) go
# Your choice (enter number or name):
# -----------------------
  • enumerate(options): Provides (index, item) pairs (e.g., (0, 'python'), (1, 'javascript')).
  • f'{index + 1}) {item}\n': Creates lines like "1) python", "2) javascript", etc.

Accepting Numeric Input (Validating Numbers)

Prompt the user until they enter a valid number corresponding to an option index.

options = ['python', 'javascript', 'typescript', 'go']
# Build the input_message as shown in 2.1...
input_message = "Pick a language:\n"
for index, item in enumerate(options): input_message += f'{index + 1}) {item}\n'
input_message += 'Your choice (enter number 1-{}): '.format(len(options))

user_input_num = ''
selected_option = None

# Keep asking until a valid number is entered
valid_numbers = [str(i) for i in range(1, len(options) + 1)] # Create ['1', '2', '3', '4']

while user_input_num not in valid_numbers:
user_input_num = input(input_message)
if user_input_num not in valid_numbers:
print(f"Invalid input. Please enter a number between 1 and {len(options)}.")

# Convert valid input string ('1', '2', etc.) to index (0, 1, etc.)
selected_index = int(user_input_num) - 1
selected_option = options[selected_index]

print(f'\nYou picked: {selected_option}')
  • valid_numbers = [str(i) for i in range(1, len(options) + 1)]: Creates a list of valid string inputs (e.g., ['1', '2', '3', '4']).
  • while user_input_num not in valid_numbers:: The loop continues as long as the input doesn't match one of the valid number strings.
  • selected_index = int(user_input_num) - 1: Converts the valid number string to an integer and subtracts 1 to get the correct 0-based list index.
  • selected_option = options[selected_index]: Retrieves the chosen item from the original list.

Accepting Text Input (Validating Names, Case-Insensitive)

Prompt the user until they enter a valid option name (ignoring case).

options = ['python', 'javascript', 'typescript', 'go']
# Build the input_message as shown in 2.1...
input_message = "Pick a language:\n"
for index, item in enumerate(options): input_message += f'{index + 1}) {item}\n'
input_message += 'Your choice (enter name): '

user_input_text = ''
selected_option = None
options_lower = [opt.lower() for opt in options] # Pre-calculate lowercase options

while user_input_text.lower() not in options_lower:
user_input_text = input(input_message)
if user_input_text.lower() not in options_lower:
print("Invalid input. Please enter one of the listed language names.")

# Find the actual option matching the input (preserving original case if needed)
# This loop finds the original casing once input is validated
for opt in options:
if opt.lower() == user_input_text.lower():
selected_option = opt
break

print(f'\nYou picked: {selected_option}')
  • options_lower = [opt.lower() for opt in options]: Creates a list of lowercase option names for validation.
  • while user_input_text.lower() not in options_lower:: Compares the lowercase user input against the list of valid lowercase options.
  • The final for loop retrieves the option from the original list that corresponds to the validated input, preserving its original capitalization if desired.

Method 2: Simple Multiple Choice Prompt (while True)

For a fixed, small number of choices, a direct while True loop with if/elif/else can be simpler.

Using Numeric Choices

selected_language = None

while True: # Loop indefinitely until a valid choice breaks it
print("\nChoose your primary backend language:")
user_input = input("1) Python | 2) Go | 3) Java [Enter 1, 2, or 3]: ")

if user_input == '1':
selected_language = "Python"
print("Excellent choice!")
break # Exit the loop
elif user_input == '2':
selected_language = "Go"
print("Speedy!")
break # Exit the loop
elif user_input == '3':
selected_language = "Java"
print("Very enterprise.")
break # Exit the loop
else:
# Invalid input, loop continues
print("Invalid choice. Please enter 1, 2, or 3.")
# 'continue' is implicit here, loop restarts

print(f"\nSelected Language: {selected_language}")
  • while True: Creates an infinite loop.
  • if/elif/elif: Checks the input against valid options ('1', '2', '3'). Remember input() returns strings.
  • break: Exits the while loop once a valid choice is made.
  • else: Handles invalid input, prints a message, and the loop repeats.

Using Alphabetic Choices (Case-Insensitive)

selected_framework = None

while True:
print("\nChoose a frontend framework:")
user_input = input("A) React | B) Vue | C) Angular [Enter A, B, or C]: ")
user_input_upper = user_input.upper() # Convert input to uppercase for comparison

if user_input_upper == 'A':
selected_framework = "React"
print("Great for components!")
break
elif user_input_upper == 'B':
selected_framework = "Vue"
print("Approachable and progressive!")
break
elif user_input_upper == 'C':
selected_framework = "Angular"
print("Full-featured framework!")
break
else:
print("Invalid choice. Please enter A, B, or C.")

print(f"\nSelected Framework: {selected_framework}")
  • user_input.upper(): Converts the user's input to uppercase, allowing the comparison (== 'A', == 'B', etc.) to work regardless of whether the user typed 'a' or 'A'.

Method 3: Using the inquirer Package (Interactive Menu)

For a more user-friendly command-line interface with arrow key navigation, use the inquirer library.

Installation

First, install the package:

pip install inquirer

Basic Usage

Use inquirer.List to present choices.

import inquirer         # Requires installation

options = ['Low', 'Medium', 'High', 'Critical']

questions = [
inquirer.List( # Type of question: List allows selection
'priority', # Internal name for the answer
message="Select the priority level", # Prompt message
choices=options, # List of choices to display
),
]

# Prompt the user and get answers
answers = inquirer.prompt(questions)

# Answers is a dictionary {'priority': 'SelectedOption'}
if answers: # Check if user didn't cancel (e.g., Ctrl+C)
selected_priority = answers['priority']
print(f"\nYou selected priority: {selected_priority}")
else:
print("\nNo option selected.")
  • This creates an interactive menu where the user can use up/down arrow keys and Enter to select an option.
  • inquirer.prompt() returns a dictionary where the keys are the names given in inquirer.List (like 'priority') and the values are the user's selections.
note

inquirer is primarily designed for Unix-like systems (Linux, macOS) and has experimental Windows support, so behavior might vary on Windows.

Choosing the Right Method

  • Numbered Options (Method 1): Good for longer lists where typing the full name is tedious but you still want to display the names. Flexible for accepting numbers or text. Requires more setup code for the prompt and validation.
  • Simple Multiple Choice (Method 2): Best for a small, fixed number of choices (e.g., 2-5 options). Very easy to implement with while True and if/elif/else.
  • inquirer (Method 3): Provides the best user experience for command-line applications with arrow key navigation. Requires installing an external library and works best on Linux/macOS.

Conclusion

Getting user input to select from a list in Python involves presenting the options clearly and validating the input.

  • For numbered lists, dynamically build the prompt using enumerate and validate input using loops and checks (either numeric or case-insensitive text).
  • For simple, fixed choices, a while True loop with if/elif/else and break is often sufficient. Remember to handle string comparisons correctly (e.g., comparing '1' not 1, using .upper() for case-insensitivity).
  • For interactive menus, the inquirer library offers a superior user experience but adds an external dependency.

Choose the method that best suits the number of options, the required input format (number vs. text), and the desired user experience.