Python sys.argv lists and indexes
Question:
In the below code I understand that sys.argv uses lists, however I am not clear on how the index’s are used here.
def main():
if len(sys.argv) >= 2:
name = sys.argv[1]
else:
name = 'World'
print 'Hello', name
if __name__ == '__main__':
main()
If I change
name = sys.argv[1]
to
name = sys.argv[0]
and type something for an argument it returns:
Hello C:Documents and SettingsfredMy DocumentsDownloadsgoogle-python-exercises
google-python-exerciseshello.py
Which kind of make sense.
Can someone explain how the 2 is used here:
if len(sys.argv) >= 2:
And how the 1 is used here:
name = sys.argv[1]
Answers:
sys.argv
is the list of arguments passed to the Python program. The first argument, sys.argv[0]
, is actually the name of the program as it was invoked. That’s not a Python thing, but how most operating systems work. The reason sys.argv[0]
exists is so you can change your program’s behaviour depending on how it was invoked. sys.argv[1]
is thus the first argument you actually pass to the program.
Because lists (like most sequences) in Python start indexing at 0, and because indexing past the end of the list is an error, you need to check if the list has length 2 or longer before you can access sys.argv[1]
.
In a nutshell, sys.argv
is a list of the words that appear in the command used to run the program. The first word (first element of the list) is the name of the program, and the rest of the elements of the list are any arguments provided. In most computer languages (including Python), lists are indexed from zero, meaning that the first element in the list (in this case, the program name) is sys.argv[0]
, and the second element (first argument, if there is one) is sys.argv[1]
, etc.
The test len(sys.argv) >= 2
simply checks wither the list has a length greater than or equal to 2, which will be the case if there was at least one argument provided to the program.
let’s say on the command-line you have:
C:> C:Documents and SettingsfredMy DocumentsDownloadsgoogle-python-exercises
google-python-exerciseshello.py John
to make it easier to read, let’s just shorten this to:
C:> hello.py John
argv
represents all the items that come along via the command-line input, but counting starts at zero (0) not one (1): in this case, “hello.py
” is element 0, “John
” is element 1
in other words, sys.argv[0] == 'hello.py'
and sys.argv[1] == 'John'
… but look, how many elements is this? 2, right! so even though the numbers are 0 and 1, there are 2 elements here.
len(sys.argv) >= 2
just checks whether you entered at least two elements. in this case, we entered exactly 2.
now let’s translate your code into English:
define main() function:
if there are at least 2 elements on the cmd-line:
set 'name' to the second element located at index 1, e.g., John
otherwise there is only 1 element... the program name, e.g., hello.py:
set 'name' to "World" (since we did not get any useful user input)
display 'Hello' followed by whatever i assigned to 'name'
so what does this mean? it means that if you enter:
- “
hello.py
“, the code outputs “Hello World
” because you didn’t give a name
- “
hello.py John
“, the code outputs “Hello John
” because you did
- “
hello.py John Paul
“, the code still outputs “Hello John
” because it does not save nor use sys.argv[2]
, which was “Paul
” — can you see in this case that len(sys.argv) == 3
because there are 3 elements in the sys.argv
list?
So if I wanted to return a first name and last name like: Hello Fred Gerbig I would use the code below, this code works but is it actually the most correct way to do it?
import sys
def main():
if len(sys.argv) >= 2:
fname = sys.argv[1]
lname = sys.argv[2]
else:
name = 'World'
print 'Hello', fname, lname
if __name__ == '__main__':
main()
Edit: Found that the above code works with 2 arguments but crashes with 1. Tried to set len to 3 but that did nothing, still crashes (re-read the other answers and now understand why the 3 did nothing). How do I bypass the arguments if only one is entered? Or how would error checking look that returned “You must enter 2 arguments”?
Edit 2: Got it figured out:
import sys
def main():
if len(sys.argv) >= 2:
name = sys.argv[1] + " " + sys.argv[2]
else:
name = 'World'
print 'Hello', name
if __name__ == '__main__':
main()
As explained in the different asnwers already, sys.argv
contains the command line arguments that called your Python script.
However, Python comes with libraries that help you parse command line arguments very easily. Namely, the new standard argparse. Using argparse
would spare you the need to write a lot of boilerplate code.
In the below code I understand that sys.argv uses lists, however I am not clear on how the index’s are used here.
def main():
if len(sys.argv) >= 2:
name = sys.argv[1]
else:
name = 'World'
print 'Hello', name
if __name__ == '__main__':
main()
If I change
name = sys.argv[1]
to
name = sys.argv[0]
and type something for an argument it returns:
Hello C:Documents and SettingsfredMy DocumentsDownloadsgoogle-python-exercises
google-python-exerciseshello.py
Which kind of make sense.
Can someone explain how the 2 is used here:
if len(sys.argv) >= 2:
And how the 1 is used here:
name = sys.argv[1]
sys.argv
is the list of arguments passed to the Python program. The first argument, sys.argv[0]
, is actually the name of the program as it was invoked. That’s not a Python thing, but how most operating systems work. The reason sys.argv[0]
exists is so you can change your program’s behaviour depending on how it was invoked. sys.argv[1]
is thus the first argument you actually pass to the program.
Because lists (like most sequences) in Python start indexing at 0, and because indexing past the end of the list is an error, you need to check if the list has length 2 or longer before you can access sys.argv[1]
.
In a nutshell, sys.argv
is a list of the words that appear in the command used to run the program. The first word (first element of the list) is the name of the program, and the rest of the elements of the list are any arguments provided. In most computer languages (including Python), lists are indexed from zero, meaning that the first element in the list (in this case, the program name) is sys.argv[0]
, and the second element (first argument, if there is one) is sys.argv[1]
, etc.
The test len(sys.argv) >= 2
simply checks wither the list has a length greater than or equal to 2, which will be the case if there was at least one argument provided to the program.
let’s say on the command-line you have:
C:> C:Documents and SettingsfredMy DocumentsDownloadsgoogle-python-exercises
google-python-exerciseshello.py John
to make it easier to read, let’s just shorten this to:
C:> hello.py John
argv
represents all the items that come along via the command-line input, but counting starts at zero (0) not one (1): in this case, “hello.py
” is element 0, “John
” is element 1
in other words, sys.argv[0] == 'hello.py'
and sys.argv[1] == 'John'
… but look, how many elements is this? 2, right! so even though the numbers are 0 and 1, there are 2 elements here.
len(sys.argv) >= 2
just checks whether you entered at least two elements. in this case, we entered exactly 2.
now let’s translate your code into English:
define main() function:
if there are at least 2 elements on the cmd-line:
set 'name' to the second element located at index 1, e.g., John
otherwise there is only 1 element... the program name, e.g., hello.py:
set 'name' to "World" (since we did not get any useful user input)
display 'Hello' followed by whatever i assigned to 'name'
so what does this mean? it means that if you enter:
- “
hello.py
“, the code outputs “Hello World
” because you didn’t give a name - “
hello.py John
“, the code outputs “Hello John
” because you did - “
hello.py John Paul
“, the code still outputs “Hello John
” because it does not save nor usesys.argv[2]
, which was “Paul
” — can you see in this case thatlen(sys.argv) == 3
because there are 3 elements in thesys.argv
list?
So if I wanted to return a first name and last name like: Hello Fred Gerbig I would use the code below, this code works but is it actually the most correct way to do it?
import sys
def main():
if len(sys.argv) >= 2:
fname = sys.argv[1]
lname = sys.argv[2]
else:
name = 'World'
print 'Hello', fname, lname
if __name__ == '__main__':
main()
Edit: Found that the above code works with 2 arguments but crashes with 1. Tried to set len to 3 but that did nothing, still crashes (re-read the other answers and now understand why the 3 did nothing). How do I bypass the arguments if only one is entered? Or how would error checking look that returned “You must enter 2 arguments”?
Edit 2: Got it figured out:
import sys
def main():
if len(sys.argv) >= 2:
name = sys.argv[1] + " " + sys.argv[2]
else:
name = 'World'
print 'Hello', name
if __name__ == '__main__':
main()
As explained in the different asnwers already, sys.argv
contains the command line arguments that called your Python script.
However, Python comes with libraries that help you parse command line arguments very easily. Namely, the new standard argparse. Using argparse
would spare you the need to write a lot of boilerplate code.