Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

substituting list comprehensions for map()

14 views
Skip to first unread message

Jon P.

unread,
Nov 2, 2009, 2:54:16 AM11/2/09
to
I'd like to do:

resultlist = operandlist1 + operandlist2

where for example

operandlist1=[1,2,3,4,5]
operandlist2=[5,4,3,2,1]

and resultlist will become [6,6,6,6,6]. Using map(), I
can do:

map(lambda op1,op2: op1 + op2, operandlist1, operandlist2)

Is there any reasonable way to do this via a list comprehension ?

Javier Collado

unread,
Nov 2, 2009, 2:58:04 AM11/2/09
to Jon P., pytho...@python.org
Hello,

I'll do the following:
[op1+op2 for op1,op2 in zip(operandlist1, operandlist2)]

Best regards,
Javier

2009/11/2 Jon P. <jbp...@gmail.com>:

> --
> http://mail.python.org/mailman/listinfo/python-list
>

Chris Rebert

unread,
Nov 2, 2009, 2:59:44 AM11/2/09
to Jon P., pytho...@python.org

results = [x+y for x,y in zip(list1, list2)]

Cheers,
Chris
--
http://blog.rebertia.com

Steven D'Aprano

unread,
Nov 2, 2009, 3:13:50 AM11/2/09
to
On Sun, 01 Nov 2009 23:54:16 -0800, Jon P. wrote:

> I'd like to do:
>
> resultlist = operandlist1 + operandlist2
>
> where for example
>
> operandlist1=[1,2,3,4,5]
> operandlist2=[5,4,3,2,1]
>
> and resultlist will become [6,6,6,6,6]. Using map(), I can do:
>
> map(lambda op1,op2: op1 + op2, operandlist1, operandlist2)


If the two lists are very large, it would be faster to use this:


from operator import add
map(add, operandlist1, operandlist2)


> Is there any reasonable way to do this via a list comprehension ?

[x+y for (x, y) in zip(operandlist1, operandlist2)]

If the lists are huge, you can save some temporary memory by replacing
zip with itertools.izip.


--
Steven

Paul Rudin

unread,
Nov 2, 2009, 3:17:59 AM11/2/09
to
"Jon P." <jbp...@gmail.com> writes:

You can do it as a list comprehension e.g. like this:

[ x + y for x, y in zip(operandlist1, operandlist2)]

Note that there is some unnecessary list building going on here and it
may be better to use itertools.izip. (In python 3 zip returns an
iterator anyhow.)

Ben Finney

unread,
Nov 2, 2009, 3:19:41 AM11/2/09
to
"Jon P." <jbp...@gmail.com> writes:

> I'd like to do:
>
> resultlist = operandlist1 + operandlist2

That's an unfortunate way of expressing it; it's valid Python syntax
that doesn't do what you're describing (in this case, it will bind
‘resultlist’ to a new list that is the *concatenation* of the two
original lists).

> map(lambda op1,op2: op1 + op2, operandlist1, operandlist2)
>
> Is there any reasonable way to do this via a list comprehension ?

Yes, just about any ‘map()’ operation has a corresponding list
comprehension. (Does anyone know of a counter-example, a ‘map()’
operation that doesn't have a correspondingly simple list
comprehension?)

For the above case, this is how it's done::

>>> operandlist1 = [1, 2, 3, 4, 5]
>>> operandlist2 = [5, 4, 3, 2, 1]
>>> resultlist = [(a + b) for (a, b) in zip(operandlist1, operandlist2)]
>>> resultlist
[6, 6, 6, 6, 6]

--
\ “Creativity can be a social contribution, but only in so far as |
`\ society is free to use the results.” —Richard Stallman |
_o__) |
Ben Finney

Bruno Desthuilliers

unread,
Nov 2, 2009, 3:49:34 AM11/2/09
to
Ben Finney a écrit :
(snip)

> Yes, just about any ‘map()’ operation has a corresponding list
> comprehension.

Right AFAICT, but:

> (Does anyone know of a counter-example, a ‘map()’
> operation that doesn't have a correspondingly simple list
> comprehension?)

... depends on your definition of "simple". There are things I'd rather
not write as a list comprehension...

Neil Crighton

unread,
Nov 2, 2009, 4:24:13 AM11/2/09
to pytho...@python.org
Steven D'Aprano <steven <at> REMOVE.THIS.cybersource.com.au> writes:

> >
> > operandlist1=[1,2,3,4,5]
> > operandlist2=[5,4,3,2,1]
> >
> > and resultlist will become [6,6,6,6,6]. Using map(), I can do:
> >
> > map(lambda op1,op2: op1 + op2, operandlist1, operandlist2)
>
> If the two lists are very large, it would be faster to use this:
>

If the two lists are *very* large and every element in each list has the same
type, you should use NumPy arrays (http://numpy.scipy.org/).

>>> import numpy
>>> operandlist1 = numpy.array([1, 2, 3, 4, 5])
>>> operandlist2 = numpy.array([5, 4, 3, 2, 1])


>>> resultlist = operandlist1 + operandlist2

>>> resultlist
array([6, 6, 6, 6, 6])


Neil


Diez B. Roggisch

unread,
Nov 2, 2009, 4:39:49 AM11/2/09
to
Steven D'Aprano schrieb:

And even more so if one needs the results one by one - then just use a
generator-expression.

Diez

Ben Finney

unread,
Nov 2, 2009, 5:01:48 AM11/2/09
to
Bruno Desthuilliers <bruno.42.de...@websiteburo.invalid> writes:

> Ben Finney a écrit :


> > (Does anyone know of a counter-example, a ‘map()’ operation that
> > doesn't have a correspondingly simple list comprehension?)
>
> ... depends on your definition of "simple". There are things I'd
> rather not write as a list comprehension...

That's why I qualified it as I did. I'd be interested to know a ‘map()’
usage where there isn't a correspondingly simple list comprehension;
that is, one that couldn't be done without being significantly more
complex than the corresponding ‘map()’ usage.

--
\ “If we have to give up either religion or education, we should |
`\ give up education.” —William Jennings Bryan, 1923-01 |
_o__) |
Ben Finney

Bruno Desthuilliers

unread,
Nov 2, 2009, 6:29:53 AM11/2/09
to
Ben Finney a écrit :

> Bruno Desthuilliers <bruno.42.de...@websiteburo.invalid> writes:
>
>> Ben Finney a écrit :
>>> (Does anyone know of a counter-example, a ‘map()’ operation that
>>> doesn't have a correspondingly simple list comprehension?)
>> ... depends on your definition of "simple". There are things I'd
>> rather not write as a list comprehension...
>
> That's why I qualified it as I did. I'd be interested to know a ‘map()’
> usage where there isn't a correspondingly simple list comprehension;
> that is, one that couldn't be done without being significantly more
> complex than the corresponding ‘map()’ usage.

I know I've seen the case, and more than once, but I'm afraid I don't
have any example to publish here - I'd need to do quite a bit of
archeology :-/

J Kenneth King

unread,
Nov 2, 2009, 8:45:28 AM11/2/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:

> On Sun, 01 Nov 2009 23:54:16 -0800, Jon P. wrote:
>
>> I'd like to do:
>>
>> resultlist = operandlist1 + operandlist2
>>
>> where for example
>>
>> operandlist1=[1,2,3,4,5]
>> operandlist2=[5,4,3,2,1]
>>
>> and resultlist will become [6,6,6,6,6]. Using map(), I can do:
>>
>> map(lambda op1,op2: op1 + op2, operandlist1, operandlist2)
>
>
> If the two lists are very large, it would be faster to use this:
>
>
> from operator import add
> map(add, operandlist1, operandlist2)

This is the best solution so far.

>
>
>> Is there any reasonable way to do this via a list comprehension ?
>
> [x+y for (x, y) in zip(operandlist1, operandlist2)]
>
> If the lists are huge, you can save some temporary memory by replacing
> zip with itertools.izip.

I understand the OP was asking for it, but list comprehensions aren't
the best solution in this case... it would just be line noise.

List comprehensions are good for one-off transformations where it would
only create a one-time method for map to use.

Kee Nethery

unread,
Nov 2, 2009, 10:24:35 AM11/2/09
to pytho...@python.org
I just noticed the tag line "a place for Python". Looked it up online (http://pyfora.org/
) and it will be interesting to see if it can fill the void that I
experience (no centralized place to post and view user submitted
sample code) in the existing Python community.

As for user community fragmentation, I would guess that someone would
be less likely to create such a site if the user community needs were
being met by the official sites. There is a place for the existing old
school interaction forums (the IRC channel, the Usenet groups and
mailing lists), but there is also a place for archived user submitted
comments.

My personal preference would be a link in each sub-paragraph in the
official documentation to a wiki page devoted to that specific aspect
of the Python language. A place were users could augment the
documentation by providing sample code and by expanding out the
documentation for those of us who don't live and breath Python in our
sleep. Real Python coders would not click on the user wiki links and
all of us newbies could communicate with each other. But until a place
like that exists, perhaps Pyfora will get us part way there.

Kee


Diez B. Roggisch

unread,
Nov 2, 2009, 10:38:06 AM11/2/09
to
Kee Nethery wrote:

> I just noticed the tag line "a place for Python". Looked it up online
> (http://pyfora.org/ ) and it will be interesting to see if it can fill the
> void that I experience (no centralized place to post and view user
> submitted sample code) in the existing Python community.

ASPN cookbook?

And I don't think that a phpBB (or commercial rip-off) forum can be good at
that - the search-function of these things sucks big time, and
classification through tagging or hierarchical organization is also not
possible.

> My personal preference would be a link in each sub-paragraph in the
> official documentation to a wiki page devoted to that specific aspect
> of the Python language. A place were users could augment the
> documentation by providing sample code and by expanding out the
> documentation for those of us who don't live and breath Python in our
> sleep. Real Python coders would not click on the user wiki links and
> all of us newbies could communicate with each other. But until a place
> like that exists, perhaps Pyfora will get us part way there.

This idea has been discussed before, and unfortunately not bore any fruits
so far - one of the few places PHP is actually better than Python. So I'd
love to see it happen.

However I totally fail to see how the pyfora are any step into that
direction.

Diez

Duncan Booth

unread,
Nov 2, 2009, 11:22:08 AM11/2/09
to
"Diez B. Roggisch" <de...@nospam.web.de> wrote:

> Kee Nethery wrote:
>> My personal preference would be a link in each sub-paragraph in the
>> official documentation to a wiki page devoted to that specific aspect
>> of the Python language. A place were users could augment the
>> documentation by providing sample code and by expanding out the
>> documentation for those of us who don't live and breath Python in our
>> sleep. Real Python coders would not click on the user wiki links and
>> all of us newbies could communicate with each other. But until a
>> place like that exists, perhaps Pyfora will get us part way there.
>
> This idea has been discussed before, and unfortunately not bore any
> fruits so far - one of the few places PHP is actually better than
> Python. So I'd love to see it happen.

One option would be to use Google sidewiki. That way we need no changes to
the existing site and people can add comments on pages or individual
paragraphs, phrases or words. It's up and running today.

However, so far as I know there isn't any easy way to find all sidewiki
comments for a site: the APIs only allow you to retrieve comments for an
individual page. (There's a sidewiki issue for this
http://code.google.com/p/gdata-issues/issues/detail?id=1493 ) If they
address this issue then the site could include a ticker of recent comments.

Also of course some people may have objections to using sidewiki e.g. on
privacy grounds.

--
Duncan Booth http://kupuguy.blogspot.com

Paul Rubin

unread,
Nov 2, 2009, 12:39:54 PM11/2/09
to
Kee Nethery <k...@kagi.com> writes:
> I just noticed the tag line "a place for Python". Looked it up online
> (http://pyfora.org/ ) and it will be interesting to see if it can fill
> the void that I experience (no centralized place to post and view
> user submitted sample code) in the existing Python community.

Something wrong with pastebin.com or any of its lookalikes?

Ben Finney

unread,
Nov 2, 2009, 5:14:05 PM11/2/09
to
J Kenneth King <ja...@agentultra.com> writes:

> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>
> > from operator import add
> > map(add, operandlist1, operandlist2)
>
> This is the best solution so far.

Strange to say it's a solution, when it doesn't solve the stated
problem: to replace use of ‘map()’ with a list comprehension.

> I understand the OP was asking for it, but list comprehensions aren't
> the best solution in this case... it would just be line noise.

I disagree; a list comprehension is often clearer than use of ‘map()’
with a lambda form, and I find it to be so in this case.

--
\ “He may look like an idiot and talk like an idiot but don't let |
`\ that fool you. He really is an idiot.” —Groucho Marx |
_o__) |
Ben Finney

Steven D'Aprano

unread,
Nov 2, 2009, 10:32:34 PM11/2/09
to
On Tue, 03 Nov 2009 09:14:05 +1100, Ben Finney wrote:

> J Kenneth King <ja...@agentultra.com> writes:
>
>> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>>
>> > from operator import add
>> > map(add, operandlist1, operandlist2)
>>
>> This is the best solution so far.
>
> Strange to say it's a solution, when it doesn't solve the stated
> problem: to replace use of ‘map()’ with a list comprehension.

In context, I wasn't giving that as a replacement for map(), but as a
replacement for map-with-a-lambda.


>> I understand the OP was asking for it, but list comprehensions aren't
>> the best solution in this case... it would just be line noise.
>
> I disagree; a list comprehension is often clearer than use of ‘map()’
> with a lambda form, and I find it to be so in this case.


You obviously don't do enough functional programming :)

Apart from an occasional brain-fart where I conflate map() with filter(),
I find them perfectly readable and sensible. The only advantages to list
comps are you can filter results with an if clause, and for simple
expressions you don't need to create a function. They're non-trivial
advantages, but for me readability isn't one of them.


--
Steven

Steven D'Aprano

unread,
Nov 2, 2009, 11:04:47 PM11/2/09
to
On Mon, 02 Nov 2009 19:19:41 +1100, Ben Finney wrote:

> "Jon P." <jbp...@gmail.com> writes:
>
>> I'd like to do:
>>
>> resultlist = operandlist1 + operandlist2
>
> That's an unfortunate way of expressing it; it's valid Python syntax
> that doesn't do what you're describing (in this case, it will bind
> ‘resultlist’ to a new list that is the *concatenation* of the two
> original lists).

True, but it is valid mathematical syntax if you interpret lists as
vectors. I'm sure there are languages where [1,2]+[3,4] will return
[4,6]. Possibly R or Mathematica?


> Yes, just about any ‘map()’ operation has a corresponding list
> comprehension. (Does anyone know of a counter-example, a ‘map()’
> operation that doesn't have a correspondingly simple list
> comprehension?)

Everyone forgets the multiple argument form of map.

map(func, s1, s2, s3, ...)

would need to be written as:

[func(t) for f in itertools.izip_longest(s1, s2, s3, ...)]

which I guess is relatively simple, but only because izip_longest() does
the hard work.


On the other hand, list comps using an if clause can't be written as pure
maps. You can do this:

[func(x) for x in seq if cond(x)]

filter(cond, map(func, seq))


but the second version may use much more temporary memory if seq is huge
and cond very rarely true.

And I don't think you could write this as a single map:

[func(a, b) for a in seq1 for b in seq2]


--
Steven

Anh Hai Trinh

unread,
Nov 2, 2009, 11:06:51 PM11/2/09
to
> Yes, just about any ‘map()’ operation has a corresponding list
> comprehension. (Does anyone know of a counter-example, a ‘map()’
> operation that doesn't have a correspondingly simple list
> comprehension?)

Try turning this into a list comprehension:

vectorsum = lambda *args: map(sum, zip(*args))

vectorsum([1,2], [3,4], [5,6])
->[9, 12]
vectorsum([1,2], [3,4], [5,6], [7,8])
->[16, 20]

Peace,

----aht

Anh Hai Trinh

unread,
Nov 2, 2009, 11:24:12 PM11/2/09
to
> On the other hand, list comps using an if clause can't be written as pure
> maps. You can do this:
>
> [func(x) for x in seq if cond(x)]
>
> filter(cond, map(func, seq))
>
> but the second version may use much more temporary memory if seq is huge
> and cond very rarely true.

You could use ifilter, imap there to reduce memory.


> And I don't think you could write this as a single map:
>
> [func(a, b) for a in seq1 for b in seq2]

Oh you surely could:

seq1, seq2 = [1,2,3], [4,5,6]

[a+b for a in seq1 for b in seq2]
->[5, 6, 7, 6, 7, 8, 7, 8, 9]

from itertools import product
map(sum, product(seq1, seq2))
->[5, 6, 7, 6, 7, 8, 7, 8, 9]


Peace,

----aht

Anh Hai Trinh

unread,
Nov 2, 2009, 11:51:46 PM11/2/09
to
> Try turning this into a list comprehension:
>
>   vectorsum = lambda *args: map(sum, zip(*args))
>
>   vectorsum([1,2], [3,4], [5,6])
> ->[9, 12]
>   vectorsum([1,2], [3,4], [5,6], [7,8])
> ->[16, 20]

Nvm, it's actually easy:
vectorsum = lambda *args: [sum(i) for i in zip(*args)]

Ben Finney

unread,
Nov 2, 2009, 11:55:20 PM11/2/09
to
Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> writes:

> On Mon, 02 Nov 2009 19:19:41 +1100, Ben Finney wrote:
>
> > "Jon P." <jbp...@gmail.com> writes:
> >
> >> I'd like to do:
> >>
> >> resultlist = operandlist1 + operandlist2
> >
> > That's an unfortunate way of expressing it; it's valid Python syntax
> > that doesn't do what you're describing (in this case, it will bind
> > ‘resultlist’ to a new list that is the *concatenation* of the two
> > original lists).
>
> True, but it is valid mathematical syntax if you interpret lists as
> vectors. I'm sure there are languages where [1,2]+[3,4] will return
> [4,6]. Possibly R or Mathematica?

Python isn't one of them, which is why I cautioned strongly against
presenting it that way in this forum.

> Everyone forgets the multiple argument form of map.
>
> map(func, s1, s2, s3, ...)
>
> would need to be written as:
>
> [func(t) for f in itertools.izip_longest(s1, s2, s3, ...)]
>
> which I guess is relatively simple, but only because izip_longest() does
> the hard work.

Yes, I would call that equivalently simple. (I also find it more
explicit and hence readable.)

--
\ “Laurie got offended that I used the word ‘puke’. But to me, |
`\ that's what her dinner tasted like.” —Jack Handey |
_o__) |
Ben Finney

Ben Finney

unread,
Nov 3, 2009, 12:01:00 AM11/3/09
to
Anh Hai Trinh <anh.ha...@gmail.com> writes:

> > Yes, just about any ‘map()’ operation has a corresponding list
> > comprehension. (Does anyone know of a counter-example, a ‘map()’
> > operation that doesn't have a correspondingly simple list
> > comprehension?)
>
> Try turning this into a list comprehension:
>
> vectorsum = lambda *args: map(sum, zip(*args))

By “this” I take you to mean “the usage of ‘map’ in this code”, since
that's the limit of my question.

>>> vectorsum = lambda *args: [sum(items) for items in zip(*args)]


>>> vectorsum([1,2], [3,4], [5,6])

[9, 12]
>>> vectorsum([1,2], [3,4], [5,6], [7,8])

[16, 20]

--
\ “The apparent lesson of the Inquisition is that insistence on |
`\ uniformity of belief is fatal to intellectual, moral, and |
_o__) spiritual health.” —_The Uses Of The Past_, Herbert J. Muller |
Ben Finney

Steven D'Aprano

unread,
Nov 3, 2009, 12:31:51 AM11/3/09
to

[sum(t) for t in zip(*args)] will do it.

>>> args = [1,2], [3,4], [5,6]
>>> [sum(t) for t in zip(*args)]
[9, 12]
>>> args = [1,2], [3,4], [5,6], [7,8]
>>> [sum(t) for t in zip(*args)]
[16, 20]

--
Steven

Sean DiZazzo

unread,
Nov 3, 2009, 1:54:42 AM11/3/09
to
On Nov 2, 9:01 pm, Ben Finney <ben+pyt...@benfinney.id.au> wrote:

prickly

M.-A. Lemburg

unread,
Nov 3, 2009, 5:27:20 AM11/3/09
to Kee Nethery, pytho...@python.org
Kee Nethery wrote:
> I just noticed the tag line "a place for Python". Looked it up online
> (http://pyfora.org/) and it will be interesting to see if it can fill

> the void that I experience (no centralized place to post and view user
> submitted sample code) in the existing Python community.

There already is a well-known site for exchanging code snippets:

The ActiveState Cookbook for Python
http://code.activestate.com/recipes/langs/python/

> As for user community fragmentation, I would guess that someone would be
> less likely to create such a site if the user community needs were being
> met by the official sites. There is a place for the existing old school
> interaction forums (the IRC channel, the Usenet groups and mailing
> lists), but there is also a place for archived user submitted comments.
>

> My personal preference would be a link in each sub-paragraph in the
> official documentation to a wiki page devoted to that specific aspect of
> the Python language. A place were users could augment the documentation
> by providing sample code and by expanding out the documentation for
> those of us who don't live and breath Python in our sleep. Real Python
> coders would not click on the user wiki links and all of us newbies
> could communicate with each other. But until a place like that exists,
> perhaps Pyfora will get us part way there.

I'm sure something like that could be added to the official
documentation. Please file a feature request for on the Python
tracker.

We could have a dedicated place on the python.org wiki to host
such snippets and then use sub-pages for the various topics.

--
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source (#1, Nov 03 2009)
>>> Python/Zope Consulting and Support ... http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611
http://www.egenix.com/company/contact/

J Kenneth King

unread,
Nov 3, 2009, 10:22:28 AM11/3/09
to
Ben Finney <ben+p...@benfinney.id.au> writes:

> J Kenneth King <ja...@agentultra.com> writes:
>
>> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>>
>> > from operator import add
>> > map(add, operandlist1, operandlist2)
>>
>> This is the best solution so far.
>
> Strange to say it's a solution, when it doesn't solve the stated
> problem: to replace use of ‘map()’ with a list comprehension.

Granted I admit this later in my post. It's not a solution to the OPs
request, but it is the best solution to such a case.

>
>> I understand the OP was asking for it, but list comprehensions aren't
>> the best solution in this case... it would just be line noise.
>
> I disagree; a list comprehension is often clearer than use of ‘map()’
> with a lambda form, and I find it to be so in this case.

The use of map expresses a value and implies the procedure by which it
is obtained.

The list comprehension expresses the procedure by which the value is
obtained.

Both have uses and in some cases a list comprehension is definitely
preferrable to a map operation.

However in this case the procedure by which we derive the value is not
important or even interesting. It is much more succinct to think of the
operation as a value and express it accordingly. There's no need to
clutter the mind with extra name bindings and iteration keywords. They
won't make our idea any more clear.

dot_product = map(mul, vec1, vec2)

vs

dot_product = [a * b for a, b in zip(vec1, vec2)]

It's very clear, at least to me, what a dot-product is in this case.
Adding in the loop construct and name bindings doesn't enhance my
understanding of what a dot-product is. I don't need to see the loop
construct at all in this case. A dot product is simply the
multiplication of each element in a vector sequence. It's more succinct
to simply think of the value rather then expressing the procedure to
construct that value.

This isn't a hammer issue. Not every problem is a nail.

Steven D'Aprano

unread,
Nov 3, 2009, 8:53:15 PM11/3/09
to
On Tue, 03 Nov 2009 10:22:28 -0500, J Kenneth King wrote:

> However in this case the procedure by which we derive the value is not
> important or even interesting. It is much more succinct to think of the
> operation as a value and express it accordingly. There's no need to
> clutter the mind with extra name bindings and iteration keywords. They
> won't make our idea any more clear.
>
> dot_product = map(mul, vec1, vec2)
>
> vs
>
> dot_product = [a * b for a, b in zip(vec1, vec2)]
>
> It's very clear, at least to me, what a dot-product is in this case.

Except it's not.

The dot product of two vectors returns a scalar, not another vector:
http://en.wikipedia.org/wiki/Dot_product

So what you want is:

dot_product = sum(map(mul, vec1, vec2))

> Adding in the loop construct and name bindings doesn't enhance my
> understanding of what a dot-product is. I don't need to see the loop
> construct at all in this case. A dot product is simply the
> multiplication of each element in a vector sequence.

What you need is to define a function dot-product, and not hijack the
name for a local value. Then the function's implementation is irrelevant
to you: it could use a list comp, or could use map, it could use a for-
loop, a while loop, recursion, or black magic:

scalar = dot_product(vec1, vec2)


--
Steven

Robert Kern

unread,
Nov 3, 2009, 11:43:45 PM11/3/09
to pytho...@python.org

Or use the appropriate libraries:

from numpy import dot

scalar = dot(vec1, vec2)

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Steven D'Aprano

unread,
Nov 4, 2009, 12:35:30 AM11/4/09
to
On Tue, 03 Nov 2009 22:43:45 -0600, Robert Kern wrote:

> Steven D'Aprano wrote:
>> On Tue, 03 Nov 2009 10:22:28 -0500, J Kenneth King wrote:
>
>>> Adding in the loop construct and name bindings doesn't enhance my
>>> understanding of what a dot-product is. I don't need to see the loop
>>> construct at all in this case. A dot product is simply the
>>> multiplication of each element in a vector sequence.
>>
>> What you need is to define a function dot-product, and not hijack the
>> name for a local value. Then the function's implementation is
>> irrelevant to you: it could use a list comp, or could use map, it could
>> use a for- loop, a while loop, recursion, or black magic:
>>
>> scalar = dot_product(vec1, vec2)
>
> Or use the appropriate libraries:
>
> from numpy import dot
>
> scalar = dot(vec1, vec2)


Why would I want to use an already existing library that is fast, well-
written and well-supported, when I can toss together a nasty kludge
myself?

--
Steven

Tim Chase

unread,
Nov 4, 2009, 6:43:30 AM11/4/09
to Steven D'Aprano, pytho...@python.org

because you want to perform a dot-product on strings?

>>> dot_product(['a', 'b', 'c'], [2,3,4])
'aabbbcccc'

[grins, ducks and scampers away after the
sum-shouldn't-special-case-strings-with-an-error thread]

-tkc

Ben Finney

unread,
Nov 4, 2009, 7:08:54 AM11/4/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:

Because using that library will ensure you can't migrate to Python 3 any
time soon?

*rimshot*

--
\ “… a Microsoft Certified System Engineer is to information |
`\ technology as a McDonalds Certified Food Specialist is to the |
_o__) culinary arts.” —Michael Bacarella |
Ben Finney

Dotan Cohen

unread,
Nov 4, 2009, 8:29:50 AM11/4/09
to Kee Nethery, pytho...@python.org
> My personal preference would be a link in each sub-paragraph in the official
> documentation to a wiki page devoted to that specific aspect of the Python
> language. A place were users could augment the documentation by providing
> sample code and by expanding out the documentation for those of us who don't
> live and breath Python in our sleep. Real Python coders would not click on
> the user wiki links and all of us newbies could communicate with each other.
> But until a place like that exists, perhaps Pyfora will get us part way
> there.
>

The PHP documentation has this feature: user comments right on the
same page (no link to a wiki, though). It's great, most of the best
usage practices that I have learned in that language came from the
user's comments, not from the official documentation itself.


--
Dotan Cohen

http://what-is-what.com
http://gibberish.co.il

J Kenneth King

unread,
Nov 4, 2009, 9:39:32 AM11/4/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:

> On Tue, 03 Nov 2009 10:22:28 -0500, J Kenneth King wrote:
>
>> However in this case the procedure by which we derive the value is not
>> important or even interesting. It is much more succinct to think of the
>> operation as a value and express it accordingly. There's no need to
>> clutter the mind with extra name bindings and iteration keywords. They
>> won't make our idea any more clear.
>>
>> dot_product = map(mul, vec1, vec2)
>>
>> vs
>>
>> dot_product = [a * b for a, b in zip(vec1, vec2)]
>>
>> It's very clear, at least to me, what a dot-product is in this case.
>
> Except it's not.
>
> The dot product of two vectors returns a scalar, not another vector:
> http://en.wikipedia.org/wiki/Dot_product
>
> So what you want is:
>
> dot_product = sum(map(mul, vec1, vec2))

Derh. Thanks for the catch. My bad.

>> Adding in the loop construct and name bindings doesn't enhance my
>> understanding of what a dot-product is. I don't need to see the loop
>> construct at all in this case. A dot product is simply the
>> multiplication of each element in a vector sequence.
>
> What you need is to define a function dot-product, and not hijack the
> name for a local value. Then the function's implementation is irrelevant
> to you: it could use a list comp, or could use map, it could use a for-
> loop, a while loop, recursion, or black magic:
>
> scalar = dot_product(vec1, vec2)

Even better.

But now I'm afraid the example is running away from the point.

So to summarize:

1. Extra name bindings and loop keywords aren't always easier to read.

2. Expressing what we want rather than how we get it is much more clear.

and (third dirty argument added)

3. List comprehensions leak their name bindings to the surrounding
scope. :p

Have a nice day. :)

Steven D'Aprano

unread,
Nov 4, 2009, 6:44:50 PM11/4/09
to
On Wed, 04 Nov 2009 23:08:54 +1100, Ben Finney wrote:

> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>
>> On Tue, 03 Nov 2009 22:43:45 -0600, Robert Kern wrote:
>> > from numpy import dot
>> >
>> > scalar = dot(vec1, vec2)
>>
>> Why would I want to use an already existing library that is fast, well-
>> written and well-supported, when I can toss together a nasty kludge
>> myself?
>
> Because using that library will ensure you can't migrate to Python 3 any
> time soon?


Why would I want to migrate to Python 3 any time soon? 2.5 and 2.6 meet
my needs (so far), and the new features in Python 3 aren't especially
compelling to me. Particularly if migrating to 3 requires me to re-write
all the libraries, where's the advantage?

--
Steven

Ben Finney

unread,
Nov 4, 2009, 9:27:09 PM11/4/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:

> On Wed, 04 Nov 2009 23:08:54 +1100, Ben Finney wrote:
>
> > Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
> >> Why would I want to use an already existing library that is fast,
> >> well- written and well-supported, when I can toss together a nasty
> >> kludge myself?
> >
> > Because using that library will ensure you can't migrate to Python 3
> > any time soon?
>
> Why would I want to migrate to Python 3 any time soon?

Sounds like you've answered the questions posed, then. Good for you!

--
\ “The whole area of [treating source code as intellectual |
`\ property] is almost assuring a customer that you are not going |
_o__) to do any innovation in the future.” —Gary Barnett |
Ben Finney

Steven D'Aprano

unread,
Nov 4, 2009, 10:00:08 PM11/4/09
to
On Thu, 05 Nov 2009 13:27:09 +1100, Ben Finney wrote:

> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>
>> On Wed, 04 Nov 2009 23:08:54 +1100, Ben Finney wrote:
>>
>> > Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> writes:
>> >> Why would I want to use an already existing library that is fast,
>> >> well- written and well-supported, when I can toss together a nasty
>> >> kludge myself?
>> >
>> > Because using that library will ensure you can't migrate to Python 3
>> > any time soon?
>>
>> Why would I want to migrate to Python 3 any time soon?
>
> Sounds like you've answered the questions posed, then. Good for you!

I was actually only being *half* tongue in cheek, which is why I left out
the smiley.

On the python-dev list at the moment is a lot of discussion on why uptake
of Python 3.1 has been slower than hoped. But one of the things that
people haven't really discussed -- or at least that I haven't seen -- is
why one would prefer 3.1 over 2.5 or 2.6.

I've played around with 3.0, and I've read the What's New for 3.1 (and am
installing 3.1 now), and while the changes look nice, I'm not sure that
they're nice enough to deal with the pain of 2to3 migration.

So how about that, 3.1 fans? What are the most compelling reasons for you
that convinced you to change?


--
Steven

Alf P. Steinbach

unread,
Nov 4, 2009, 10:33:52 PM11/4/09
to
* Steven D'Aprano:

Since I'm just learning Python and am an utter Python novice this might not
amount to much, but it's in the nature of language evolution that the new more
or less incompatible version *does* become the dominant one, and for new things
it's then a good idea to adopt the coming in future generally used version of
the language, instead of being left in a quagmire trying to catch up with new
versions of tools and libs suddenly not so compatible with the old code.

This happened with e.g. C++ standardization in 1998. The whole standard library
was revamped and put in a namespace, and old headers like [iostream.h] were
removed. And as with the Python "/" operator core language functionality was
changed: in C++98 'new' suddenly threw (Pythoneese raised) an exception instead
of returning 0 on failure, and templates were suddenly "two phase" with quite
different semantics, so that much old code didn't even compile, and when it did,
didn't work correctly.

But those who chose to stay behind paid and still for some pay the price, having
to use ages old tools and libs. One amusing or sad (depending one's point of
view) variant was where firms chose to get along with the language evolution,
tools etc., but still restrict themselves to not only pre-standard C++ but some
early 1980's version, not much more than "C with classes" or "better C". For
example, at Google they generally don't use C++ exceptions, presumably because
they have a large code base of non-exception-safe code. Still, assuming that's
the rationale, it would surprise me if they don't use exceptions in their new code.

This is perhaps an heretical view, that the new language version's advantages
don't matter so much as the fact that the new language version is incompatible,
viewing that incompatibility as a /reason/ to change.

But I think it's realistic; getting the advantages (such as with Python 3.x
improved efficiency for range etc., and thus also more clear notation) is just
an added bonus.


Cheers & hth.,

- Alf

Mensanator

unread,
Nov 5, 2009, 1:25:46 AM11/5/09
to
On Nov 4, 9:00 pm, Steven D'Aprano

Itertools is worth the price of admission. As far as the "pain of
migration"
is concerned, less annoying than a mosquito bite.

>
> --
> Steven- Hide quoted text -
>
> - Show quoted text -

Rustom Mody

unread,
Nov 5, 2009, 2:33:26 AM11/5/09
to pytho...@python.org
Steven D'Aprano wrote:
> On the python-dev list at the moment is a lot of discussion on why uptake
> of Python 3.1 has been slower than hoped. But one of the things that
> people haven't really discussed -- or at least that I haven't seen -- is
> why one would prefer 3.1 over 2.5 or 2.6.

> So how about that, 3.1 fans? What are the most compelling reasons for you


> that convinced you to change?

Why I am back on 2.5/2.6

Case 1
I need to use the library construct for parsing binary files
http://construct.wikispaces.com/
I tried porting it to python 3 but was not successful.
Dont pretend to have tried very hard but...
1. The library is quite well written but I dont know its internals
2. In fact I am just familiarisng myself with its usage
3. Intricacies of 2to3 changes their whys and wherefores are quite
foreign to me -- specifically unicode matters have always frightened
me.

Case 2
I prefer to use python-mode in emacs for development
python 3 has broken python-mode by removing execfile
I suggested a (1-line) fix https://bugs.launchpad.net/python-mode/+bug/450552
Its still pending.

Case 3
Python3 has a windows installer but no deb packages for ubuntu/debian
I installed with the installer on windows
and compiled the sources on linux (with some help of this list)
However compilation takes time and converts my laptop into a toaster
Given the above 2 cases I seem to have wasted the wearntear of my laptop.

Summary:
The attraction of python is not primarily in the language.
Its not even in the batteries that are *included* but the non-included
ones that are available.
If that set is significantly sparser for 3 than for 2.x I dont see how
many people can adopt it even if they wish to

[Excludes the academics in ivory towers who discuss the subtle
qualities of different languages.
Been-there-done-that (was in a university for 20 years) and if I was
in that context I would not use 2 or 3 but lisp, haskell or some other
beautiful wonderment from arcanaland]

Ethan Furman

unread,
Nov 5, 2009, 11:04:44 AM11/5/09
to pytho...@python.org

Python 3 is more pythonic. ;-)

Cleaner, more consistent, etc.

~Ethan~

Terry Reedy

unread,
Nov 5, 2009, 5:31:46 PM11/5/09
to pytho...@python.org
Steven D'Aprano wrote:

> I've played around with 3.0, and I've read the What's New for 3.1 (and am
> installing 3.1 now), and while the changes look nice, I'm not sure that
> they're nice enough to deal with the pain of 2to3 migration.

I am in a different position since I did not have current code that
would need migrating.

> So how about that, 3.1 fans? What are the most compelling reasons for you
> that convinced you to change?

I am writing a book on algorithms that uses a subset of 3.1 as the
algorithm language. It it simply cleaner and easier to explain to people
not already familiar with the quirks of 2.x. One small but
important-to-me example. I do not need to put 'from __future__ import
integerdivision' (or whatever the incantation is) as the top of files.
Hence I do not need to waste energy (mime and readers) explaining
furture imports and the specifics of the old versus new meaning of int/int.

While I initially resisted the text==unicode change, I now see it as
essential to the future of Python as a world algorithm language.

I admit that I am more bothered about the leftover quirks (to me --
sludge) in 2.x than most.

Unless you are the author/maintainer of an essential library, I have no
opinion as to what you do with old code, or even what you use for new code.

I do care about people trying to disparage or sabotage 3.x.

Terry Jan Reedy

geremy condra

unread,
Nov 5, 2009, 5:42:42 PM11/5/09
to Terry Reedy, pytho...@python.org
On Thu, Nov 5, 2009 at 5:31 PM, Terry Reedy <tjr...@udel.edu> wrote:
> Steven D'Aprano wrote:
>
>> I've played around with 3.0, and I've read the What's New for 3.1 (and am
>> installing 3.1 now), and while the changes look nice, I'm not sure that
>> they're nice enough to deal with the pain of 2to3 migration.
>
> I am in a different position since I did not have current code that would
> need migrating.
>
>> So how about that, 3.1 fans? What are the most compelling reasons for you
>> that convinced you to change?
>
> I am writing a book on algorithms that uses a subset of 3.1 as the algorithm
> language. It it simply cleaner and easier to explain to people not already
> familiar with the quirks of 2.x. One small but important-to-me example. I do
> not need to put 'from __future__ import integerdivision' (or whatever the
> incantation is) as the top of files. Hence I do not need to waste energy
> (mime and readers) explaining furture imports and the specifics of the old
> versus new meaning of int/int.

I agree. Most of my code is primarily mathematical, and while I personally
see the move away from functional programming techniques as a minor
misstep, the cleanliness of it all more than makes up for that.

Geremy Condra

0 new messages