[Tutor] who makes FOR loop quicker

Steven D'Aprano steve at pearwood.info
Wed Aug 5 15:19:05 CEST 2015

On Wed, Aug 05, 2015 at 10:53:14AM +0300, John Doe wrote:
> To pass by reference or by copy of - that is the question from hamlet. 
> ("hamlet" - a community of people smaller than a village python3.4-linux64)

Python *never* uses either pass by reference OR pass by value (copy). 
Please read this:


> xlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> i = 0
> for x in xlist:
> 	print(xlist)
> 	print("\txlist[%d] = %d" % (i, x))
> 	if x%2 == 0 :
> 		xlist.remove(x)
> 	print(xlist, "\n\n")
> 	i = i + 1

It is risky to remove items from a list as you iterate over it. Also, 
there is no need to manually increment the index i. Instead, use 
enumerate(alist), which returns (index, value) for each value in alist. 
But before iterating over the list, make a copy. The easiest way to copy 
a list is to take a slice using alist[start:end]. If you leave both 
start and end out, it copies the entire list.

First improvement:

for i, x in enumerate(xlist[:]):  # list[:] makes a copy of the list
    print("\txlist[%d] = %d" % (i, x))
    if x%2 == 0 :
    print(xlist, "\n\n")

But we can improve this even more. Instead of *removing* items we don't 
want, we should *add* items we do want. This will almost always be 
faster, especially for big lists:

new = []
for i, x in enumerate(xlist):  # No need for a copy now.
    print("xlist[%d] = %d" % (i, x))
    if x%2 != 0 :
    print(new, "\n\n")

And in fact we can write this even more compactly:

new = [x for x in xlist if x%2 != 0]

although in this case you don't get the benefit of printing. This is 
called a "list comprehension", and we can break it down:

[x  # the expression to be appended to the new list
 for x in xlist  # the "for loop" part
 if x%2 != 0  # optional condition that applies to the expression


More information about the Tutor mailing list