SHORT ANSWER

Use the nargs option or the 'append' setting of the action option (depending on how you want the user interface to behave).

nargs

parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567

nargs='+' takes 1 or more arguments, nargs='*' takes zero or more.

append

parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567

With append you provide the option multiple times to build up the list.

Don't use type=list!!! - There is probably no situation where you would want to use type=list with argparse. Ever.


LONG ANSWER

Let's take a look in more detail at some of the different ways one might try to do this, and the end result.

import argparse

parser = argparse.ArgumentParser()

# By default it will fail with multiple arguments.
parser.add_argument('--default')

# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)

# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')

# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')

# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)

# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')

# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
    if value is not None:
        print(value)

Here is the output you can expect:

$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ # Quotes won't help here... 
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']

$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]

$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']

$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]

$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]

$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']

Takeaways:

  • Use nargs or action='append'
    • nargs can be more straightforward from a user perspective, but it can be unintuitive if there are positional arguments because argparse can't tell what should be a positional argument and what belongs to the nargs; if you have positional arguments then action='append' may end up being a better choice.
    • The above is only true if nargs is given '*', '+', or '?'. If you provide an integer number (such as 4) then there will be no problem mixing options with nargs and positional arguments because argparse will know exactly how many values to expect for the option.
  • Don't use quotes on the command line1
  • Don't use type=list, as it will return a list of lists
    • This happens because under the hood argparse uses the value of type to coerce each individual given argument you your chosen type, not the aggregate of all arguments.
    • You can use type=int (or whatever) to get a list of ints (or whatever)

1: I don't mean in general.. I mean using quotes to pass a list to argparse is not what you want.

Answer from SethMMorton on Stack Overflow
Top answer
1 of 13
1688

SHORT ANSWER

Use the nargs option or the 'append' setting of the action option (depending on how you want the user interface to behave).

nargs

parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567

nargs='+' takes 1 or more arguments, nargs='*' takes zero or more.

append

parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567

With append you provide the option multiple times to build up the list.

Don't use type=list!!! - There is probably no situation where you would want to use type=list with argparse. Ever.


LONG ANSWER

Let's take a look in more detail at some of the different ways one might try to do this, and the end result.

import argparse

parser = argparse.ArgumentParser()

# By default it will fail with multiple arguments.
parser.add_argument('--default')

# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)

# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')

# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')

# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)

# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')

# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
    if value is not None:
        print(value)

Here is the output you can expect:

$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ # Quotes won't help here... 
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']

$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]

$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']

$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]

$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]

$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']

Takeaways:

  • Use nargs or action='append'
    • nargs can be more straightforward from a user perspective, but it can be unintuitive if there are positional arguments because argparse can't tell what should be a positional argument and what belongs to the nargs; if you have positional arguments then action='append' may end up being a better choice.
    • The above is only true if nargs is given '*', '+', or '?'. If you provide an integer number (such as 4) then there will be no problem mixing options with nargs and positional arguments because argparse will know exactly how many values to expect for the option.
  • Don't use quotes on the command line1
  • Don't use type=list, as it will return a list of lists
    • This happens because under the hood argparse uses the value of type to coerce each individual given argument you your chosen type, not the aggregate of all arguments.
    • You can use type=int (or whatever) to get a list of ints (or whatever)

1: I don't mean in general.. I mean using quotes to pass a list to argparse is not what you want.

2 of 13
157

I prefer passing a delimited string which I parse later in the script. The reasons for this are; the list can be of any type int or str, and sometimes using nargs I run into problems if there are multiple optional arguments and positional arguments.

parser = ArgumentParser()
parser.add_argument('-l', '--list', help='delimited list input', type=str)
args = parser.parse_args()
my_list = [int(item) for item in args.list.split(',')]

Then,

python test.py -l "265340,268738,270774,270817" [other arguments]

or,

python test.py -l 265340,268738,270774,270817 [other arguments]

will work fine. The delimiter can be a space, too, which would though enforce quotes around the argument value like in the example in the question.

Or you can use a lambda type as suggested in the comments by Chepner:

parser.add_argument('-l', '--list', help='delimited list input', 
    type=lambda s: [int(item) for item in s.split(',')])
🌐
Python
docs.python.org › 3 › library › argparse.html
argparse — Parser for command-line options, arguments and subcommands
Source code: Lib/argparse.py Tutorial: This page contains the API reference information. For a more gentle introduction to Python command-line parsing, have a look at the argparse tutorial. The arg...
Discussions

Argparse with arbitrary numbers of arguments but they should occur in pairs

according to the docs you can use the nargs option of .add_argument to gather lists of values.

you'll need to process that list manually like u/mac-reid shows but at least you'll be able to combine it with standard args

here's what I would do:

#!/usr/bin/env python
import sys
import argparse

def dualiter(singleiter):
    iterable = iter(singleiter)
    while True:
        yield next(iterable), next(iterable)
    
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    # ...other args...
    parser.add_argument('filepairs', nargs='*')
    args = parser.parse_args()
        
    if len(args.filepairs) % 2:
        parser.error('filepairs arg should be pairs of values')
        
    for fname, fnum in dualiter(args.filepairs):
        print fname, fnum
More on reddit.com
🌐 r/learnpython
7
6
January 30, 2014
CLI: populate List with the * wildcard (like argparse nargs='+')
There was an error while loading. Please reload this page · Currently, to pass several arguments to a List, the syntax is quite difficult, you need to do something like More on github.com
🌐 github.com
4
July 15, 2024
what is the cleanest way to argparse 2-4 names separated by spaces?
You can use a positional parameter with nargs="+": import argparse parser = argparse.ArgumentParser() parser.add_argument("names", nargs="+") parser.add_argument("--optional") args = parser.parse_args(["a", "b", "c", "--optional", "d"]) print(args) Namespace(names=['a', 'b', 'c'], optional='d') That the length of names is between 2 and 4 you'll need to verify for yourself. More on reddit.com
🌐 r/learnpython
2
3
August 23, 2022
How do I pass my own arguments to argparse without using the command line?
If you're just talking about while you're developing/debugging, it's pretty simple. Just create a launch.json, Run and Debug tab on the left > create a launch.json file. The JSON can look something like this: { "version": "0.2.0", "configurations": [ { "name": "Python: Current File", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", "args": ["-i", "input.txt", "-o", "output.txt"] } ] } main.py import sys print(sys.argv) Hit F5 (or start debugging) Output ['c:\\main.py', '-i', 'input.txt', '-o', 'output.txt'] Edit: To be clear, sys.argv was just to illustrate the point, because it's simpler and faster, but it'll work with argparse as well. More on reddit.com
🌐 r/learnpython
17
3
February 9, 2024
🌐
GeeksforGeeks
geeksforgeeks.org › python › how-to-pass-a-list-as-a-command-line-argument-with-argparse
How to pass a list as a command-line argument with argparse? - GeeksforGeeks
July 23, 2025 - In this example, the list_of_ints function takes a string as input and returns a list of Python integers. The type parameter of add_argument is set to list_of_ints, so when parse_args is called, the string value of --int-list is converted into a list of integers. ... # import module import argparse # Define a custom argument type for a list of integers def list_of_ints(arg): return list(map(int, arg.split(','))) # Create an ArgumentParser object parser = argparse.ArgumentParser() # Add an argument for the list of integers parser.add_argument('--int-list', type=list_of_ints) # Parse the command-line arguments args = parser.parse_args() # Use the list of integers in your script print(args.int_list)
🌐
Flexiple
flexiple.com › python › python-argparse-list
Python argparse - Flexiple
Python argparse is a powerful module that simplifies the process of parsing command-line arguments in Python scripts. In this comprehensive blog, we'll explore the ins and outs of using argparse to handle lists of values as command-line arguments.
🌐
Python documentation
docs.python.org › 3 › howto › argparse.html
Argparse Tutorial — Python 3.14.4 documentation
author, Tshepang Mbambo,. This tutorial is intended to be a gentle introduction to argparse, the recommended command-line parsing module in the Python standard library. Concepts: Let’s show the sor...
🌐
Mimo
mimo.org › glossary › python › argparse
Python argparse: Syntax, Usage, and Examples
Now args.ids is ['1', '2', '3']. This approach lets you handle python argparse list inputs without post-processing.
🌐
DataCamp
datacamp.com › tutorial › python-argparse
Master Python's argparse Module: Build Better CLIs | DataCamp
December 3, 2024 - When developing command-line programs in Python, you may encounter scenarios requiring more complex argument parsing. Python's argparse module includes several features to address these complex requirements, allowing you to develop flexible and user-friendly interfaces.
Find elsewhere
🌐
Python
bugs.python.org › issue16399
Issue 16399: argparse: append action with default list adds to list instead of overriding - Python tracker
November 4, 2012 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/60603
🌐
Real Python
realpython.com › command-line-interfaces-python-argparse
Build Command-Line Interfaces With Python's argparse – Real Python
December 14, 2024 - $ python ls.py -h usage: ls [-h] [-l] path List the content of a directory positional arguments: path options: -h, --help show this help message and exit -l, --long Thanks for using ls! :) Now the output shows the description message right after the usage message and the epilog message at the end of the help text. Help groups are another interesting feature of argparse.
🌐
Python Module of the Week
pymotw.com › 2 › argparse
argparse – Command line option and argument parsing. - Python Module of the Week
If the argument allows multiple values, values will be a list even if it only contains one item. The value of option_string also depends on the original argument specifiation. For positional, required, arguments, option_string is always None. $ python argparse_custom_action.py Initializing CustomAction dest = 'a' option_strings = ['-a'] required = False Initializing CustomAction dest = 'm' nargs = '*' option_strings = ['-m'] required = False Initializing CustomAction dest = 'positional' option_strings = [] required = True Processing CustomAction for "a" parser = 4299616464 values = 'value' option_string = '-a' Processing CustomAction for "m" parser = 4299616464 values = ['multi-value'] option_string = '-m' Processing CustomAction for "positional" parser = 4299616464 values = 'positional-value' option_string = None Namespace(a='VALUE', m=['MULTI-VALUE'], positional='POSITIONAL-VALUE')
🌐
Reddit
reddit.com › r/learnpython › argparse with arbitrary numbers of arguments but they should occur in pairs
r/learnpython on Reddit: Argparse with arbitrary numbers of arguments but they should occur in pairs
January 30, 2014 -

I'm wanting to use argparse to parse command-line arguments for a script I'm writing. I want it to be able to specify something on the command-line like the following:

python myscript.py file1 10 file2 5 file3 1 file4 915 

for an arbitrary number of files. With each file I want to associate a number (which corresponds to something I will do with the data in that file). I know I can use a single commandline argument with nargs='*' and it will consume all of the commandline arguments at once. However, this seems non-ideal because then I'll have to take the parsed list of arguments and break it up into a list of tuples like

[(file1,10), (file2,5),....]

and I also won't get the parser to be able to check that the argument after each file name is a number. What's the best way to implement this?

Edit: Thanks to everyone for their suggestions!

🌐
GitHub
gist.github.com › kanekomasahiro › 0a8eebdc59f9ad3ae1c7b2c76ef8b2e8
argparseでlistを受け取る · GitHub
argparseでlistを受け取る · Raw · parser_list.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
GitHub
github.com › omni-us › jsonargparse › issues › 550
CLI: populate List with the * wildcard (like argparse nargs='+') · Issue #550 · omni-us/jsonargparse
July 15, 2024 - def main(foo: List[str]): pass if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('foo', type=str, nargs='+') main(**vars(parser.parse_args())) so you can call it like · python jsonargparse_demo.py a* and match all files starting with "a" I guess you can already do this using the ArgumentParser from jsonargparse but I like CLI so much, it's really convenient otherwise, thanks again for the great library btw!
Author   PaulLerner
🌐
Readthedocs
ironpython-test.readthedocs.io › en › latest › library › argparse.html
15.4. argparse — Parser for command-line options, arguments and sub-commands — IronPython 2.7.2b1 documentation
This class is deliberately simple, just an object subclass with a readable string representation. If you prefer to have dict-like view of the attributes, you can use the standard Python idiom via vars(): >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> args = parser.parse_args(['--foo', 'BAR']) >>> vars(args) {'foo': 'BAR'}
🌐
Nokia
network.developer.nokia.com › static › sr › learn › pysros › latest › argparse.html
argparse – Argument parser functions — pySROS 26.3.1 documentation
The ArgumentParser.parse_args() method runs the parser and places the extracted data in a argparse.Namespace object: args = parser.parse_args() print(args.filename, args.count, args.verbose) The following code is a Python program that takes a list of integers and produces either the sum or the max:
🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-use-argparse-to-write-command-line-programs-in-python
How To Use argparse to Write Command-Line Programs in Python | DigitalOcean
March 11, 2021 - As you may have guessed, the -h ... variant python3 aquarium.py --help) prints out the help text. The help text, effectively, is a longer version of the usage text that was outputted in the previous example when you supplied invalid arguments. Notably, the help text also includes the custom description string of List fish in an aquarium that you instantiated the ArgumentParser with earlier on in this tutorial. By default, when you write a CLI using argparse you’ll ...
🌐
Reddit
reddit.com › r/learnpython › what is the cleanest way to argparse 2-4 names separated by spaces?
r/learnpython on Reddit: what is the cleanest way to argparse 2-4 names separated by spaces?
August 23, 2022 -

so I have made a program that takes in a full name as the primary parameter. Usually it is 2 names but sometimes there is 3 or 4. I have been using sys.argv[1:] to just get all the names from the command line, it has been working well but I am now looking into using argparse to add some optional arguments and it is creating some conflicts.

argparse gives an error if I try to use it only for optional args and continue using sys.argv for the positional, I would also have to remove the optional args from the list. I'd prefer to just use argparse but after reading around the docs a bit I am not seeing a way to just get all the positional args. Is there anything that doesn't involve creating 4 positional args or is that just the nature of them?

🌐
Kodeclik
kodeclik.com › python-argumentparser-list
Passing a list as a command-line argument to Python
September 24, 2024 - In our case, assume that instead of adding two numbers we desire to add a list of numbers, i.e., a list whose length is not predetermined. To handle such scenarios, we can use the nargs parameter of the add_argument method.
🌐
Google Groups
groups.google.com › g › comp.lang.python › c › JmUc-fm6E4Q
argparse: delimiter for argparse list arguments
On 2021-08-03, Roel Schroeven <ro...@roelschroeven.net> wrote: > Jon Ribbens via Python-list schreef op 3/08/2021 om 17:48: >> On 2021-08-03, Michael Torrie <tor...@gmail.com> wrote: >> > On 8/2/21 1:43 PM, Sven R. Kunze wrote: >> >> maybe, I am missing something here but is it possible to specify a >> >> delimiter for list arguments in argparse: >> >> >> >> https://docs.python.org/3/library/argparse.html >> >> >> >> Usually, '--' is used to separate two lists (cf.
🌐
Medium
medium.com › @thesyscoder › ultimate-use-of-python-argparser-4516f1f7d047
Ultimate Use of Python ArgParser. Use python ArgParser for multivalued… | by Pruthviraj Sonawane | Medium
January 14, 2023 - ''' import argparse class PythonArgparser(): def __init__(self, argsGroup): self.argsGroup = argsGroup pass # Print argparser values and data type def printArgParserValues(self): print(f"ArgParser Values : {self.argsGroup}") print(f"Type of ArgParser Value : {type(self.argsGroup)}") pass pass if __name__ == "__main__": parser = argparse.ArgumentParser( description="PYTHON MULTI VALUED UNLIMITED COMMAND LINE ARGUMENT PARSER") parser.add_argument('-ag', '--argsGroup', required=True, nargs='*', metavar=('varGroup', 'values'), action='append', help="Enter variable group and values") args = parser.parse_args() obj = PythonArgparser(args.argsGroup) obj.printArgParserValues() pass · The above code snippet is creating a nested list of arguments.