Explain Codes LogoExplain Codes Logo

How can I pass a list as a command-line argument with argparse?

python
argument-parsing
command-line-arguments
argparse
Alex KataevbyAlex Kataev·Oct 15, 2024
TLDR

To pass a list of items to a script, leverage argparse with nargs='*'. This will collect all the values into a list. Here's how:

import argparse parser = argparse.ArgumentParser() parser.add_argument('--items', nargs='*', help='Pass the items, great taste not included') args = parser.parse_args() print(args.items)

You can now use it like so:

python script.py --items apple banana cherry

This will render args.items as, surprise surprise, ['apple', 'banana', 'cherry'].

Argument list depth: diving deeper

Exact list size: no more, no less

Want to play bouncer with your list elements? Use nargs='+' or nargs=3 to mandate at least one or exactly three elements like some super exclusive club.

parser.add_argument('--numbers', nargs=3, type=int, help='Three numbers walk into a bar...')

Now only three integers can join the list party.

Invoking JSON: for when lists get complex

With complex list structures, input a JSON string and then call json.loads to parse it like a boss:

import json parser.add_argument('--data', type=json.loads, help='Enter the matrix... or just a JSON string with list data')

Use it as such:

python script.py --data '["first", {"second": "yes, I know it is weird"}]'

List arguments: from zero to hero

To give a default value to your list argument, assign the default parameter:

parser.add_argument('--ids', nargs='*', type=int, default=[1,2,3], help='Your default group of friends when everyone else is busy')

Mopping up the leftovers

Want to capture all remaining arguments after a designated point? Use argparse.REMAINDER like a hoover for loose arguments:

parser.add_argument('remainder', nargs=argparse.REMAINDER)

Now everything in your command call after the first recognized flag will be gathered, no man left behind.

Building a better mousetrap: robust argument handling

Fancy input parsing: split personalities welcome

Got a string with a delimiter you want to split up? Use a custom type for a smoother ride:

parser.add_argument('--coords', type=lambda x: x.split(','), help='Point to X,Y Coordinates without causing an existential crisis')

Call it as so:

python script.py --coords "10,20" "30,40"

Playing safe with given choices

Your list only takes predefined values? Use choices to restrict and authenticate input, like bouncer 2.0:

parser.add_argument('--level', choices=['easy', 'medium', 'hard'], nargs='+', help='Choose your difficulty, choose your destiny')

Making friends with negative numbers

When handling numeric values that may be negative, use this tip:

parser.add_argument('--', nargs='*', type=int, help='ITALIAN ACCENT: Put in the numbers. Even if they owe you money.')

By using --, you signal the end of options and negative numbers won't be mistaken as flags. Real problem solver, this one.

Special case handling: a guide

Repeat after me: append action

Want to use the same argument more than once? Use action='append':

parser.add_argument('--tag', action='append', help='DJ Name Generator: add a tag to your DJ name')

Use it on repeat:

python script.py --tag DJ --tag Python

List elements' dress code: integers only

Want to ensure that your list contains elements of a specific type, say integers? Use type=int to enforce a strict dress code:

parser.add_argument('--scores', nargs='+', type=int, help='Input list of scores. And no, you can\'t score an A here.')

Mixing it up: options and positional arguments

Mixing positional arguments and options in a command call can get tricky. Always specify nargs to avoid a cocktail of confusion and parsing errors.