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

question about list extension

0 views
Skip to first unread message

J

unread,
Apr 16, 2010, 9:41:29 AM4/16/10
to Python List
Ok... I know pretty much how .extend works on a list... basically it
just tacks the second list to the first list... like so:

>>> lista=[1]
>>> listb=[2,3]
>>> lista.extend(listb)
>>> print lista;
[1, 2, 3]

what I'm confused on is why this returns None:

>>> lista=[1]
>>> listb=[2,3]
>>> print lista.extend(listb)
None
>>> print lista
[1, 2, 3]

So why the None? Is this because what's really happening is that
extend() and append() are directly manipulating the lista object and
thus not actuall returning a new object?

Even if that assumption of mine is correct, I would have expected
something like this to work:

>>> lista=[1]
>>> listb=[2,3]
>>> print (lista.extend(listb))
None

The reason this is bugging me right now is that I'm working on some
code. My program has a debugger class that takes a list as it's only
(for now) argument. That list, is comprised of messages I want to
spit out during debug, and full output from system commands being run
with Popen...

So the class looks something like this:

class debugger():
def printout(self,info):
for line in info:
print "DEBUG: %s" % line


and later on, it get's called like this

meminfo = Popen('cat
/proc/meminfo',shell=True,stdout=PIPE).communicate[0].splitlines()

if debug:
debugger.printout(meminfo)

easy enough....

BUT, what if I have several lists I want to pass on multiple lists...

So changing debugger.printout() to:

def printout(self,*info):

lets me pass in multiple lists... and I can do this:

for tlist in info:
for item in tlist:
print item

which works well...

So, what I'm curious about, is there a list comprehension or other
means to reduce that to a single line?

I tried this, which didn't work because I'm messing up the syntax, somehow:

def func(*info)
print [ i for tlist in info for i in tlist ]

so can someone help me understand a list comprehension that will turn
those three lines into on?

It's more of a curiosity thing at this point... and not a huge
difference in code... I was just curious about how to make that work.

Cheers,

Jeff

Bruno Desthuilliers

unread,
Apr 16, 2010, 10:23:04 AM4/16/10
to
J a écrit :

> Ok... I know pretty much how .extend works on a list... basically it
> just tacks the second list to the first list... like so:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> lista.extend(listb)
>>>> print lista;
> [1, 2, 3]
>
> what I'm confused on is why this returns None:

> So why the None? Is this because what's really happening is that


> extend() and append() are directly manipulating the lista object and
> thus not actuall returning a new object?

Exactly.

> Even if that assumption of mine is correct, I would have expected
> something like this to work:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> print (lista.extend(listb))
> None

So what ? It JustWork(tm). list.extend returns None, so "None" is
printed !-)


(snip)

> So changing debugger.printout() to:
>
> def printout(self,*info):
>
> lets me pass in multiple lists... and I can do this:
>
> for tlist in info:
> for item in tlist:
> print item
>
> which works well...
>
> So, what I'm curious about, is there a list comprehension or other
> means to reduce that to a single line?

Why do you think the above code needs to be "reduced to a single line" ?
What's wrong with this snippet ???


> It's more of a curiosity thing at this point... and not a huge
> difference in code... I was just curious about how to make that work.

Uh, ok.

What about:

from itertools import chain

def printout(*infos):
print "\n".join("%s" % item for item in chain(*infos))


HTH


Lie Ryan

unread,
Apr 16, 2010, 10:37:50 AM4/16/10
to
On 04/16/10 23:41, J wrote:
> Ok... I know pretty much how .extend works on a list... basically it
> just tacks the second list to the first list... like so:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> lista.extend(listb)
>>>> print lista;
> [1, 2, 3]
>
> what I'm confused on is why this returns None:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> print lista.extend(listb)
> None
>>>> print lista
> [1, 2, 3]
>
> So why the None? Is this because what's really happening is that
> extend() and append() are directly manipulating the lista object and
> thus not actuall returning a new object?

In python every function that does not explicitly returns a value or use
a bare return returns None. So:

def foo():
pass
def bar():
return

print foo()
print bar()

you can say that returning None is python's equivalent to void return
type in other languages.

> Even if that assumption of mine is correct, I would have expected
> something like this to work:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> print (lista.extend(listb))
> None

Why would these has to be different?
print None
print (None)

<snip>

> So, what I'm curious about, is there a list comprehension or other
> means to reduce that to a single line?

from itertools import chain
def printout(*info):
print '\n'.join(map(str, chain(*info)))

or using generator comprehension

from itertools import chain
def printout(*info):
print '\n'.join(str(x) for x in chain(*info))

J. Cliff Dyer

unread,
Apr 16, 2010, 10:59:12 AM4/16/10
to Lie Ryan, pytho...@python.org


It's even easier if you don't need to modify lista.

print lista + listb


Terry Reedy

unread,
Apr 16, 2010, 3:16:55 PM4/16/10
to pytho...@python.org
On 4/16/2010 9:41 AM, J wrote:
> Ok... I know pretty much how .extend works on a list... basically it
> just tacks the second list to the first list... like so:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> lista.extend(listb)
>>>> print lista;
> [1, 2, 3]

This shows right here that lista is extended in place. If you are not
convinced, print(id(lista)) before and after.

> what I'm confused on is why this returns None:
>
>>>> lista=[1]
>>>> listb=[2,3]
>>>> print lista.extend(listb)
> None

It is conventional in Python (at least the stdlib) that methods that
mutate mutable objects 'in-place' return None to clearly differentiate
them from methods that return new objects. There are pluses and minuses
but such it is.

Terry Jan Reedy

J

unread,
Apr 16, 2010, 3:34:20 PM4/16/10
to Terry Reedy, pytho...@python.org
On Fri, Apr 16, 2010 at 15:16, Terry Reedy <tjr...@udel.edu> wrote:
> On 4/16/2010 9:41 AM, J wrote:
>>
>> Ok... I know pretty much how .extend works on a list... basically it
>> just tacks the second list to the first list... like so:
>>
>>>>> lista=[1]
>>>>> listb=[2,3]
>>>>> lista.extend(listb)
>>>>> print lista;
>>
>> [1, 2, 3]
>
> This shows right here that lista is extended in place. If you are not
> convinced, print(id(lista)) before and after.

Thanks for the explanations, everyone...

I was just a bit confused about how .extend was working... I
originally thought that it returned a new object and linked lista to
that, but I realize that it directly manipulates the list object
instead...

I'm not sure why I got that idea stuck in my head, but it was there,
so I asked :)

0 new messages