[Tutor] for vs while

Kent Johnson kent37 at tds.net
Fri Sep 28 17:14:48 CEST 2007


James wrote:
> All,
> 
> I have a dumb question...hopefully someone can shed some light on the  
> difference between for and while in the situation below.
> 
> I'm trying to iterate through a list I've created.  The list consists  
> of a command, followed by a 'logging' message (a message printed to a  
> console or log file after the command is run).
> 
> Here's a small snippet of code:
> 
> 	# a list which includes (1) a command, and (2) something to be  
> dumped into a log file after the command runs
> 	stuff = [ ["cat /etc/password"] , ["viewed /etc/password"] ]
> 
> 	#works
> 	i = 0 ; j = 1
> 	while i < len( stuff ):
> 		os.system( str( stuff[ i ] ) )
> 		print stuff[ j ]
> 		i += 1 ; j += 1
> 
> The while loop does precisely what it should do: it runs the first  
> command using os.system(), and then prints out the string in the  
> second position of the list.

Are you sure? When I run this I get
sh: line 1: [cat /etc/password]: No such file or directory
['viewed /etc/password']
sh: line 1: [viewed /etc/password]: No such file or directory

and then an IndexError. It is calling os.system() on the string 
representation of a list, and it should increment i and j by 2 each time 
through the loop.

Here is a version that works for me:

stuff = [ "cat /etc/password" , "viewed /etc/password" ]

#works
i = 0
while i < len( stuff ):
	os.system( str( stuff[ i ] ) )
	print stuff[ i+1 ]
	i += 2


> Then I tried to do the same thing with a for loop that looks  
> logically equivalent.  I replaced the while loop with this for loop:
> 
> 	# doesn't work
> 	for i in len( stuff ):
> 		os.system( stuff[ i ] )
> 		j = i + 1
> 		print stuff[ j ]
> 
> Python doesn't like it, though.  It gives me the following error:
> 
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: 'int' object is not iterable
> 
> What precisely causes this error?  I come from a C background, and  
> while and for loops can be molded to do precisely the same thing; it  
> doesn't seem like this is the case in this scenario.

Right. Python for loops are not like anything in C. They iterate over 
the values of a sequence. The thing after 'in' has to be an instance of 
a sequence such as a list or tuple, not an integer. (Technically it has 
to be an instance of an iterable but I don't want to confuse the issue.)

The way I would write this program would be to make 'stuff' a list of 
pairs, where each pair contains a command and the value to print:

# Note the parentheses which define a tuple
stuff = [ ("cat /etc/password" , "viewed /etc/password") ]

# The for statement assigns the elements of each tuple to cmd and echo
for cmd, echo in stuff:
     os.system(cmd)
     print echo

It's worth your time learning about Python data structures and for 
loops. They are very powerful and useful and unlike anything built-in to 
C. With a background in C you should find the official tutorial pretty 
easy to read:
http://docs.python.org/tut/tut.html

Kent


More information about the Tutor mailing list