Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #60069 > unrolled thread

zip list, variables

Started byflebber <flebber.crue@gmail.com>
First post2013-11-20 02:06 -0800
Last post2013-11-21 09:58 +0100
Articles 6 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  zip list, variables flebber <flebber.crue@gmail.com> - 2013-11-20 02:06 -0800
    Re: zip list, variables Peter Otten <__peter__@web.de> - 2013-11-20 11:38 +0100
    Re: zip list, variables Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-11-20 12:45 +0200
      Re: zip list, variables flebber <flebber.crue@gmail.com> - 2013-11-20 12:05 -0800
        Re: zip list, variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-21 01:03 +0000
        Re: zip list, variables Peter Otten <__peter__@web.de> - 2013-11-21 09:58 +0100

#60069 — zip list, variables

Fromflebber <flebber.crue@gmail.com>
Date2013-11-20 02:06 -0800
Subjectzip list, variables
Message-ID<31cfb6e8-aa7e-46c2-ae0b-18d0d66e7bed@googlegroups.com>
If 

c = map(sum, zip([1, 2, 3], [4, 5, 6]))

c
Out[7]: [5, 7, 9]

why then can't I do this? 

a = ([1, 2], [3, 4])

b = ([5, 6], [7, 8])

c = map(sum, zip(a, b))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-cc046c85514b> in <module>()
----> 1 c = map(sum, zip(a, b))

TypeError: unsupported operand type(s) for +: 'int' and 'list'

How can I do this legally?

Sayth

[toc] | [next] | [standalone]


#60070

FromPeter Otten <__peter__@web.de>
Date2013-11-20 11:38 +0100
Message-ID<mailman.2958.1384943908.18130.python-list@python.org>
In reply to#60069
flebber wrote:

> If
> 
> c = map(sum, zip([1, 2, 3], [4, 5, 6]))
> 
> c
> Out[7]: [5, 7, 9]
> 
> why then can't I do this?
> 
> a = ([1, 2], [3, 4])
> 
> b = ([5, 6], [7, 8])
> 
> c = map(sum, zip(a, b))
> 
---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call
> last) <ipython-input-3-cc046c85514b> in <module>()
> ----> 1 c = map(sum, zip(a, b))
> 
> TypeError: unsupported operand type(s) for +: 'int' and 'list'
> 
> How can I do this legally?

You are obscuring the issue with your map-zippery. The initial value of 
sum() is 0, so if you want to "sum" lists you have to provide a start value, 
typically an empty list:

>>> sum([[1],[2]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>> sum([[1],[2]], [])
[1, 2]

Applying that to your example:

>>> def list_sum(items):
...     return sum(items, [])
... 
>>> map(list_sum, zip(a, b))
[[1, 2, 5, 6], [3, 4, 7, 8]]

Alternatively, reduce() does not require an initial value:

>>> map(functools.partial(reduce, operator.add), zip(a, b))
[[1, 2, 5, 6], [3, 4, 7, 8]]

But doing it with a list comprehension is the most pythonic solution here...

[toc] | [prev] | [next] | [standalone]


#60071

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2013-11-20 12:45 +0200
Message-ID<qoteh6bwduh.fsf@ruuvi.it.helsinki.fi>
In reply to#60069
flebber <flebber.crue@gmail.com> writes:

> If 
> 
> c = map(sum, zip([1, 2, 3], [4, 5, 6]))
> 
> c
> Out[7]: [5, 7, 9]
> 
> why then can't I do this? 
> 
> a = ([1, 2], [3, 4])
> 
> b = ([5, 6], [7, 8])
> 
> c = map(sum, zip(a, b))
> ---------------------------------------------------------------------------
> TypeError                                 Traceback (most recent call last)
> <ipython-input-3-cc046c85514b> in <module>()
> ----> 1 c = map(sum, zip(a, b))
> 
> TypeError: unsupported operand type(s) for +: 'int' and 'list'

The error message comes from sum(([1,2],[5,6])), where start defaults
to 0. A way to understand what is happening is to inspect zip(a,b),
notice that the first element of zip(a,b) is ([1,2],[5,6]), and then
find out what sum(([1,2],[5,6])) is. The extra parentheses may seem a
bit subtle, and at least in Python 3, zip and map return opaque
objects, so it does take a bit to get used to all the details,

The offending operands to '+' are 0 and [1,2].

> How can I do this legally?

I think the easiest is [ x + y for x, y in zip(a,b) ] if you want
concatenation, and something like the following if you want a nested
numerical addition:

  >>> [ [ x + y for x, y in zip(x,y) ] for x, y in zip(a,b) ]
  [[6, 8], [10, 12]]

There is probably a way to use map and sum for this, together with the
mechanisms that change arguments to lists or vice versa (the syntax
involves *), and partial application to specify a different start for
sum if you want concatenation, but I doubt you can avoid some sort of
nesting in the expression, and I doubt it will be clearer than the
above suggestions. But someone may well show a way. (Sorry if this
paragraph sounds like so much gibberish.)

[toc] | [prev] | [next] | [standalone]


#60132

Fromflebber <flebber.crue@gmail.com>
Date2013-11-20 12:05 -0800
Message-ID<898792ac-2101-4b92-86e1-f4f9c986de28@googlegroups.com>
In reply to#60071
Thank you for the replies.

Looking at the replies I am wondering which solution is more scalable. At the moment it is only 2 nested lists but what about 5, 10, 20 or more?

Should I start looking into numpy to handle this or will list comprehension
  >>> [ [ x + y for x, y in zip(x,y) ] for x, y in zip(a,b) ] 
Be sufficient ?

Thanks

Sayth

[toc] | [prev] | [next] | [standalone]


#60150

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-11-21 01:03 +0000
Message-ID<528d5beb$0$29992$c3e8da3$5496439d@news.astraweb.com>
In reply to#60132
On Wed, 20 Nov 2013 12:05:38 -0800, flebber wrote:

> Thank you for the replies.
> 
> Looking at the replies I am wondering which solution is more scalable.
> At the moment it is only 2 nested lists but what about 5, 10, 20 or
> more?
>
> Should I start looking into numpy to handle this or will list
> comprehension
>   >>> [ [ x + y for x, y in zip(x,y) ] for x, y in zip(a,b) ]
> Be sufficient ?

Be sufficient for what? You've deleted all context from your post, so I 
have no clue what you're talking about.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#60159

FromPeter Otten <__peter__@web.de>
Date2013-11-21 09:58 +0100
Message-ID<mailman.3004.1385024316.18130.python-list@python.org>
In reply to#60132
flebber wrote:

> Thank you for the replies.
> 
> Looking at the replies I am wondering which solution is more scalable. At
> the moment it is only 2 nested lists but what about 5, 10, 20 or more?
> 
> Should I start looking into numpy to handle this or will list
> comprehension
>   >>> [ [ x + y for x, y in zip(x,y) ] for x, y in zip(a,b) ]
> Be sufficient ?

I would certainly prefer

>>> a + b
array([[ 6,  8],
       [10, 12]])

over the incomprehensible comprehension. But if it is the only usecase for 
numpy in your script and you are OK with its current performance, just put 
your listcomp into an aptly named function. Then you can write the easily 
understandable

c = matrix_add(a, b)

and avoid the numpy dependency. 

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web