[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:
http://import-that.dreamwidth.org/1130.html
> 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(xlist)
print("\txlist[%d] = %d" % (i, x))
if x%2 == 0 :
xlist.remove(x)
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 :
new.append(x)
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
]
--
Steve
More information about the Tutor
mailing list