Performance of list comprehensions vs. map
aleax at aleax.it
Fri Sep 7 10:28:11 CEST 2001
"Chris Barker" <chrishbarker at home.net> wrote in message
news:3B981539.6126C949 at home.net...
> What about the input list? If I call a:
> l2 = map(function, l1)
> and another thread is altering l1 at the same time, will that effect l2?
Definitely! It would be horrible for map to take a snapshot "behind
your back" of l1 -- it's trivially easy for YOU to explicitly make
a temporary copy, just map(function, l1[:]), if you want that, while,
if map violated all normal Pythonic expectations by taking a snapshot,
it would be very hard for you to get back to normal Pythonic behavior.
There doesn't have to be any threading involved for the effect
>>> def function(x):
... return x+l1.pop()
[9, 9, 9, 9, 9]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
As function modifies global modifiable object l1, it makes a
big difference whether map is using l1 itself or a snapshot
copy thereof. If you want a copy, ask for a copy -- exactly
as you would, e.g., in a for loop whose body may need to
modify the sequence on which the for is looping, you then
for x in thelist:
for x in thelist[:]:
or, for maximum clarity/explicitness:
for x in copy.copy(thelist):
> This is what is scary to me.
I don't really understand why. It's *normal* to take a
copy/snapshot of a modifiable container in a threaded
environment, so you can release locks fast AND not have
the container change behind your back -- and here you
don't even need the locking since thelist[:] is atomic.
(It's less normal to have a function modify global
state, as it ain't in general good programming practice,
but we all fall from grace from time to time, no?-).
> >I suggested threads as a
> > way that object bindings could change during the execution of a chunk of
> > code, but the example above demonstrates it just as well without using
> > threads.
> well, it demonstrates re-binding of the generating function, not the
> source list being altered.. the later I find a lot more scary, and can't
> imagine how it could happen in a single thread.
Let's not confuse *re-binding* of the sequence (which would have no effect
on any of map, filter, reduce, list comprehension, for loops - each
takes a *reference* to the sequence at the start, of course) with
*alteration* (modification) of the sequence object.
More information about the Python-list