2

I'm new to using the arparse module in python and am hoping someone can help me with the following problem. I am specifying a variable number of files as inputs using:

parser = argparse.ArgumentParser(description='Get Files')    
parser.add_argument('-i','--input', help='Input file(s)',required=True, nargs='+') 
args = parser.parse_args()

I would like to specify a variable number of file inputs, each with an associated value of 1 or 2 and am not sure how to do this.

I would like the program to work so that my command line entry should be:

MyProgram.py -i myfile.txt 2 secondfile.txt 1 ...

Once I have this working how do I call each file in the program?

4 Answers 4

2

It would be clearer to have -i once for each pair of inputs, like this:

parser.add_argument("-i", "--input", nargs=2, action='append')

Now, args.input would be a list of lists, like so

 [ ['myfile.txt', 2], ['secondfile.txt', 1] ]

It does require slightly more typing for the user, since -i needs to be explicitly typed once per file.

Another option is to specify each argument as a single word, then parse the word using the type argument. I would get rid of the -i argument as well and use positional arguments for required "options".

parser.add_argument('input', nargs='+', type=lambda x: x.rsplit(":", 2))

Usage would be

myscript.py myfile.txt:1 secondfile.txt:2 ...
Sign up to request clarification or add additional context in comments.

Comments

1

Your code is functional. You could use the grouper recipe to loop through args.input two items at a time:

import argparse
parser = argparse.ArgumentParser(description='Get Files')    
parser.add_argument('-i','--input', help='Input file(s)',required=True, nargs='+') 
args = parser.parse_args()
for filename, num in zip(*[iter(args.input)]*2):
    print(filename, num)
    # with open(filename) as f:
    #     ....

yields

('myfile.txt', '2')
('secondfile.txt', '1')

1 Comment

It is worth noting that since python 3.12, grouper recipe is a builtin function in itertools named batched: docs.python.org/3/library/itertools.html#itertools.batched The only difference is that batched does not fill the last group in case the length of the iterable is not fully dividable by n
0

You might be best off using sys.argv as,

import sys, os

variables = list()
filenames = list()

if( len( sys.argv ) > 1 ):
    if( sys.argv[1] == '-i' )or( sys.argv[1] == '--input' ):
        N = len( sys.argv[1:] )
        for i in range( 2, N, 2 ):
            variables.append( int( sys.argv[i] ) )
            filenames.append( sys.argv[i+1] )

for file in filenames:
    # do something here
    os.system( 'less '+file )

I haven't tested this, but that should work.

Comments

0

Try this:

parser = argparse.ArgumentParser(description='Get Files')    
parser.add_argument('-i','--input', help='Input file(s)',
    required=True, nargs='+', action='append')

args = parser.parse_args()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.