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

do you master list comprehensions?

4 views
Skip to first unread message

Will Stuyvesant

unread,
Dec 13, 2004, 3:51:25 PM12/13/04
to
Here is a question about list comprehensions [lc]. The
question is dumb because I can do without [lc]; but I am
posing the question because I am curious.

This:

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>> result = []
>>> for d in data:
... for w in d:
... result.append(w)
>>> print result
['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

puts all the words in a list, like I want.

How to do this with [lc] instead of for-loops?

I tried funnies like [[w for w in L] for L in data],
that is correct syntax, but you'd never guess.

I know, silly! No need for [lc]! So there's my
question. I am sure a one-liner using [lc] will be very
enlightening. Like studying LISP.


--
I wish there was a knob on the TV to turn up the intelligence.
There's a knob called `brightness', but it doesn't work.
-- Gallagher

Max M

unread,
Dec 13, 2004, 4:07:19 PM12/13/04
to
Will Stuyvesant wrote:

> I tried funnies like [[w for w in L] for L in data],
> that is correct syntax, but you'd never guess.

That is absolutely correct. It's not a funnie at all. If you find it odd
it's only because you are not used to list comprehensiones.

In that case you might be more comfortable with:

data = [['foo','bar','baz'],['my','your'],['holy','grail']]
result = []

for l in data:
result += l


--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science

Steven Bethard

unread,
Dec 13, 2004, 4:09:00 PM12/13/04
to
Will Stuyvesant wrote:
>>>>data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>>>result = []
>>>>for d in data:
>
> ... for w in d:
> ... result.append(w)
>
>>>>print result
>
> ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
>

Take advantage of the fact that you can have more than one 'for' in a
list comprehension:

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]

>>> [item for item_list in data for item in item_list]


['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

Steve

Peter Otten

unread,
Dec 13, 2004, 4:08:32 PM12/13/04
to
Will Stuyvesant wrote:

>>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>>> result = []
>>>> for d in data:
> ... for w in d:
> ... result.append(w)
>>>> print result
> ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
>
> puts all the words in a list, like I want.
>
> How to do this with [lc] instead of for-loops?

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]

>>> [w for d in data for w in d]


['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

See how the for expressions in the list comprehension exactly match your
nested for loops? That's all there is to it.

Peter

Diez B. Roggisch

unread,
Dec 13, 2004, 4:20:12 PM12/13/04
to
>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>> [e for l in data for e in l]

['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
--
Regards,

Diez B. Roggisch

Fredrik Lundh

unread,
Dec 13, 2004, 4:48:53 PM12/13/04
to pytho...@python.org
Max M wrote:

>> I tried funnies like [[w for w in L] for L in data],
>> that is correct syntax, but you'd never guess.
>
> That is absolutely correct. It's not a funnie at all. If you find it odd it's only because you are
> not used to list comprehensiones.

well, syntactically correct or not, it doesn't do what he want...

> In that case you might be more comfortable with:
>
> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
> result = []
> for l in data:
> result += l

how about (slightly evil):

result = []; map(result.extend, data)

</F>

Max M

unread,
Dec 13, 2004, 6:41:36 PM12/13/04
to
Fredrik Lundh wrote:
> Max M wrote:
>
>
>>>I tried funnies like [[w for w in L] for L in data],
>>
>>That is absolutely correct. It's not a funnie at all.
>
> well, syntactically correct or not, it doesn't do what he want...

Doh! *I* might not be used to list comprehensions then... You are right.

That example could have been expressed more clearly as:

result = data

;-)

Luis M. Gonzalez

unread,
Dec 13, 2004, 8:44:19 PM12/13/04
to
I guess the simplest to do it is like this:

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]

>>> result=[w for d in data for w in d]

Luis M. Gonzalez

unread,
Dec 13, 2004, 8:44:33 PM12/13/04
to
I guess the simplest way to do it is like this:

>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]

>>> result=[w for d in data for w in d]

James Stroud

unread,
Dec 13, 2004, 9:13:16 PM12/13/04
to pytho...@python.org
Here is one for arbitrary depth:

def unroll(ary):
unrolled = []
for item in ary:
# add test for your favorite sequence type
if ( type(item) == types.ListType or \
type(item) == types.TupleType \
):
unrolled.extend(unroll(item))
else:
unrolled.append(item)
return unrolled

>>> unroll([[1, 2, 3], ('fred', 'barney', ['wilma', 'betty']), 'dino'])
[1, 2, 3, 'fred', 'barney', 'wilma', 'betty', 'dino']


On Monday 13 December 2004 12:51 pm, Will Stuyvesant wrote:
> Here is a question about list comprehensions [lc]. The
> question is dumb because I can do without [lc]; but I am
> posing the question because I am curious.
>
> This:
> >>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
> >>> result = []
> >>> for d in data:
>
> ... for w in d:
> ... result.append(w)
>
> >>> print result
>
> ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
>
> puts all the words in a list, like I want.
>
> How to do this with [lc] instead of for-loops?
>
> I tried funnies like [[w for w in L] for L in data],
> that is correct syntax, but you'd never guess.
>
> I know, silly! No need for [lc]! So there's my
> question. I am sure a one-liner using [lc] will be very
> enlightening. Like studying LISP.

--
James Stroud, Ph.D.
UCLA-DOE Institute for Genomics and Proteomics
611 Charles E. Young Dr. S.
MBI 205, UCLA 951570
Los Angeles CA 90095-1570
http://www.jamesstroud.com/

Jeremy Bowers

unread,
Dec 14, 2004, 12:30:43 AM12/14/04
to
On Tue, 14 Dec 2004 00:41:36 +0100, Max M wrote:

> Fredrik Lundh wrote:
>> Max M wrote:
>>
>>
>>>>I tried funnies like [[w for w in L] for L in data],
>>>
>>>That is absolutely correct. It's not a funnie at all.
>>
>> well, syntactically correct or not, it doesn't do what he want...
>
> Doh! *I* might not be used to list comprehensions then... You are right.
>
> That example could have been expressed more clearly as:
>
> result = data

result = data[:]

:-)

Fredrik Lundh

unread,
Dec 14, 2004, 2:44:10 AM12/14/04
to pytho...@python.org
James Stroud wrote:

> Here is one for arbitrary depth:
>
> def unroll(ary):
> unrolled = []
> for item in ary:
> # add test for your favorite sequence type
> if ( type(item) == types.ListType or \
> type(item) == types.TupleType \
> ):
> unrolled.extend(unroll(item))
> else:
> unrolled.append(item)
> return unrolled
>

>>>> unroll([[1, 2, 3], ('fred', 'barney', ['wilma', 'betty']), 'dino'])
> [1, 2, 3, 'fred', 'barney', 'wilma', 'betty', 'dino']

or, shorter:

>>> from Tkinter import _flatten as unroll
>>> (1, 2, 3, 'fred', 'wilma', 'betty', 'dino')

(alright, it returns a tuple, but that can be easily fixed, if necessary)

</F>

Timothy Babytch

unread,
Dec 14, 2004, 5:49:59 AM12/14/04
to
Will Stuyvesant wrote:

>>>>data = [['foo','bar','baz'],['my','your'],['holy','grail']]

sum(data, [])

['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']

The second parameter passed to sum is just to overrride default
initial value "zero".

--
Timothy Babytch

Steven Bethard

unread,
Dec 14, 2004, 12:21:16 PM12/14/04
to

It's worth keeping in mind that this solution has the same efficiency
problems that a loop that =+ strings does:

> python -m timeit -s "data = [range(10) for _ in range(100)]"
"sum(data, [])"
1000 loops, best of 3: 530 usec per loop

> python -m timeit -s "data = [range(10) for _ in range(100)]" "[w for

d in data for w in d]"

10000 loops, best of 3: 151 usec per loop

> python -m timeit -s "data = [range(10) for _ in range(1000)]"
"sum(data, [])"
10 loops, best of 3: 54.2 msec per loop

> python -m timeit -s "data = [range(10) for _ in range(1000)]" "[w for

d in data for w in d]"

100 loops, best of 3: 1.75 msec per loop

The sum function used in this way (or a loop with a +=) is O(N**2) while
the LC is O(N).

Steve

Fredrik Lundh

unread,
Dec 14, 2004, 12:41:23 PM12/14/04
to pytho...@python.org
Steven Bethard wrote:

> > python -m timeit -s "data = [range(10) for _ in range(1000)]"
> "sum(data, [])"
> 10 loops, best of 3: 54.2 msec per loop
>
> > python -m timeit -s "data = [range(10) for _ in range(1000)]" "[w for
> d in data for w in d]"
> 100 loops, best of 3: 1.75 msec per loop
>
> The sum function used in this way (or a loop with a +=) is O(N**2) while the LC is O(N).

also:

timeit -s "data = [range(10) for _ in range(1000)]" "L = sum(data, [])"
10 loops, best of 3: 4.02e+004 usec per loop

timeit -s "data = [range(10) for _ in range(1000)]" "L = [w for d in data for w in d]"
1000 loops, best of 3: 1.12e+003 usec per loop

timeit -s "data = [range(10) for _ in range(1000)]" "L = []; map(L.extend, data)"
1000 loops, best of 3: 283 usec per loop

timeit -s "data = [range(10) for _ in range(1000)]; from Tkinter import _flatten" "L =
_flatten(data)"
1000 loops, best of 3: 308 usec per loop

(the last one supports arbitrary nestings, the others don't)

</F>

Nick Coghlan

unread,
Dec 15, 2004, 7:21:53 AM12/15/04
to Python List
Will Stuyvesant wrote:
> Here is a question about list comprehensions [lc]. The
> question is dumb because I can do without [lc]; but I am
> posing the question because I am curious.
>
> This:
>
>
>>>>data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>>>result = []
>>>>for d in data:
>
> ... for w in d:
> ... result.append(w)
>
>>>>print result
>
> ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']
>
> puts all the words in a list, like I want.

There's a way to avoid generating the intermediate list if you don't actually
need it (e.g. you want to feed the sequence to another method):

.>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
.>>> from itertools import chain
.>>> result = "".join(chain(*data))
'foobarbazmyyourholygrail'


Some timing with integers:

C:\>python -m timeit -s "data = [range(x) for x in range(1000)]" "L= []; map(L.e
xtend, data); max(L)"
10 loops, best of 3: 78.5 msec per loop

C:\>python -m timeit -s "data = [range(x) for x in range(1000)]; from Tkinter im
port _flatten" "max(_flatten(data))"
10 loops, best of 3: 58.4 msec per loop

C:\>python -m timeit -s "data = [range(x) for x in range(1000)]; from itertools
import chain" "max(chain(*data))"
10 loops, best of 3: 43 msec per loop

And with strings:

C:\>python -m timeit -s "data = [map(str, range(x)) for x in range(1000)]" "L= [
]; map(L.extend, data); ''.join(L)"
10 loops, best of 3: 106 msec per loop

C:\>python -m timeit -s "data = [map(str, range(x)) for x in range(1000)]; from
Tkinter import _flatten" "''.join(_flatten(data))"
10 loops, best of 3: 85.4 msec per loop

C:\>python -m timeit -s "data = [map(str, range(x)) for x in range(1000)]; from
itertools import chain" "''.join(chain(*data))"
10 loops, best of 3: 1.2 sec per loop ****** OUCH!!

C:\>python -m timeit -s "data = [map(str, range(x)) for x in range(1000)]; from
itertools import chain" "''.join(list(chain(*data)))"
10 loops, best of 3: 107 msec per loop


Yikes - looks like chain() really sucks for str.join. However, the addition of
the 'list' call makes a big difference. Maybe PySequence_Fast should be called
PySequence_SlowAsADeadDingo() in this case ;)

(FYI, I filed bug report #1085744 on SF about this)

Cheers,
Nick.

--
Nick Coghlan | ncog...@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net

Matthew Moss

unread,
Dec 15, 2004, 2:07:08 PM12/15/04
to
Diez B. Roggisch wrote:
> >>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
> >>> [e for l in data for e in l]
> ['foo', 'bar', 'baz', 'my', 'your', 'holy', 'grail']


Okay, I tried this in an interactive Python session and it works as
stated. My question is, why? How is the interpreter parsing that list
expression that it makes sense?

Fredrik Lundh

unread,
Dec 15, 2004, 2:27:20 PM12/15/04
to pytho...@python.org
Matthew Moss wrote:

the language reference has the answer:

http://www.python.org/doc/2.3.4/ref/lists.html

"... the elements of the new list are those that would be produced
by considering each of the 'for' or 'if' clauses a block, nesting
from left to right, and evaluating the expression to produce a list
element each time the innermost block is reached."

or, conceptually, the compiler strips off the expression, and then
inserts newlines, colons and indentation, and wraps the expression
in an append statement.

so

[e for l in data for e in l]

behaves like:

result = []
for l in data:
for e in l:
result.append(e)

except that it's an expression, and the result variable is hidden. (and
the compiler and the runtime is of course free to implement this in a
more efficient way)

</F>

Will Stuyvesant

unread,
Dec 14, 2004, 8:56:18 AM12/14/04
to
Okay that was fun. Enlightening as I hoped. unroll() in Python, for
arbitrary depth, _flatten in Tkinter (what else is in Tkinter!), sum()
abuse.

The sum(data,[]) was funniest, it works like ((['foo','bar'] + []) +
['my','your']) + ['holy','grail']. Before I think of such things I
have already coded an algorithm in imperative style. Guess I have not
been exposed to functional programming enough.

Stefan Behnel

unread,
Dec 16, 2004, 5:30:16 AM12/16/04
to

Nick Coghlan schrieb:

>>>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>>>> result = []
>>>>> for d in data:
>
> .>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
> .>>> from itertools import chain
> .>>> result = "".join(chain(*data))
> 'foobarbazmyyourholygrail'

This is the first time I see that and I totally like the idea of writing
".>>>" instead of ">>>" at the beginning of a line. Thank you Dr. Dobb!
It's unfortunate for c.l.py that Python uses ">>>" as the default prompt
as it messes up the display on mail/news readers that provide "syntax
highlighting" for quotes.

I wish everyone would write examples that way! On the other hand - three
levels of quoting are really rare, maybe it would be easier to change that
in the mail readers...

... or in Py3k ?

Stefan

Roel Schroeven

unread,
Dec 16, 2004, 7:35:25 AM12/16/04
to
Stefan Behnel wrote:
>
> Nick Coghlan schrieb:
>
>>>>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>>>>>> result = []
>>>>>> for d in data:
>>
>>
>> .>>> data = [['foo','bar','baz'],['my','your'],['holy','grail']]
>> .>>> from itertools import chain
>> .>>> result = "".join(chain(*data))
>> 'foobarbazmyyourholygrail'
>
>
> This is the first time I see that and I totally like the idea of writing
> ".>>>" instead of ">>>" at the beginning of a line. Thank you Dr. Dobb!
> It's unfortunate for c.l.py that Python uses ">>>" as the default prompt
> as it messes up the display on mail/news readers that provide "syntax
> highlighting" for quotes.

Off topic, but indeed: I use Quote Colors in Mozilla which is very nice
for reading mails or news posts with quotes, but it's very confusing
with Python's prompt.

Prepending every line with . is not an ideal solution though... I think
it gets tiresome very quickly.

--
"Codito ergo sum"
Roel Schroeven

Nick Coghlan

unread,
Dec 16, 2004, 9:22:19 AM12/16/04
to Python List
Roel Schroeven wrote:

> Stefan Behnel wrote:
>> This is the first time I see that and I totally like the idea of
>> writing ".>>>" instead of ">>>" at the beginning of a line. Thank you
>> Dr. Dobb! It's unfortunate for c.l.py that Python uses ">>>" as the
>> default prompt as it messes up the display on mail/news readers that
>> provide "syntax highlighting" for quotes.

I use Thunderbird, and started doing it so I could read my own posts. I did copy
it from someone, though (but I can't recall who).

The trick can also be useful for web tools that strip leading whitespace.

> Prepending every line with . is not an ideal solution though... I think
> it gets tiresome very quickly.

Aye, can't argue with that. It does have the virtues of reliability and
portability, though :)

Nick Coghlan

unread,
Dec 16, 2004, 9:30:46 AM12/16/04
to Python List
Nick Coghlan wrote:
> (FYI, I filed bug report #1085744 on SF about this)

And Raymond Hettinger was able to decipher my somewhat incoherent rambling (tip:
don't try to write bug reports in the wee hours of the morning) and produce a
potentially useful modification to PySequence_Tuple.

Anyway, I guess the results I got emphasizes the fact that it's important to
measure performance of the actual methods you're using on representative input
data, rather than relying on overly simple demonstrators.

And, of course, don't be *too* concerned about optimisations until you know you
actually have a performance problem. . .

Steve Holden

unread,
Dec 16, 2004, 12:00:34 PM12/16/04
to
Nick Coghlan wrote:

> Roel Schroeven wrote:
>
>> Stefan Behnel wrote:
>>
>>> This is the first time I see that and I totally like the idea of
>>> writing ".>>>" instead of ">>>" at the beginning of a line. Thank you
>>> Dr. Dobb! It's unfortunate for c.l.py that Python uses ">>>" as the
>>> default prompt as it messes up the display on mail/news readers that
>>> provide "syntax highlighting" for quotes.
>
>
> I use Thunderbird, and started doing it so I could read my own posts. I
> did copy it from someone, though (but I can't recall who).
>
> The trick can also be useful for web tools that strip leading whitespace.
>
>> Prepending every line with . is not an ideal solution though... I
>> think it gets tiresome very quickly.
>
>
> Aye, can't argue with that. It does have the virtues of reliability and
> portability, though :)
>
> Cheers,
> Nick.
>

$ python
Python 2.4 (#1, Dec 4 2004, 20:10:33)
[GCC 3.3.3 (cygwin special)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.ps1 = ".>>> "; sys.ps2 = ".... "
.>>> print """\
.... It isn't that hard"""
It isn't that hard
.>>>

Would it work, I wonder, with a leading space on the prompt? That might
be a valid change to the standard prompt. Let's see

>>> This line isn't really quoted three times.

regards
Steve
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119

Keith Dart

unread,
Dec 16, 2004, 1:15:43 PM12/16/04
to

What I do is set Python's sys.ps1 variable to something else. I have a
module called "interactive" that I import implicitly by shell alias:

py='python -i -c '\''import interactive'\'

Which, among other things, sets the prompt to "Python> "

433 $ py
Python> print "This has no leader that screws up email programs."
This has no leader that screws up email programs.
Python>

--
\/ \/
(O O)
-- --------------------oOOo~(_)~oOOo----------------------------------------
Keith Dart <kd...@kdart.com>
public key: ID: F3D288E4
============================================================================

Roel Schroeven

unread,
Dec 16, 2004, 2:04:51 PM12/16/04
to
Steve Holden wrote:
> Nick Coghlan wrote:
> $ python
> Python 2.4 (#1, Dec 4 2004, 20:10:33)
> [GCC 3.3.3 (cygwin special)] on cygwin
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import sys
> >>> sys.ps1 = ".>>> "; sys.ps2 = ".... "
> .>>> print """\
> .... It isn't that hard"""
> It isn't that hard
> .>>>
>
> Would it work, I wonder, with a leading space on the prompt? That might
> be a valid change to the standard prompt. Let's see
>
> >>> This line isn't really quoted three times.

Seems to work :) Now let's hope lots of people will use an approach like
that for code sent to the various Python newsgroups and mailing lists.

Kent Johnson

unread,
Dec 16, 2004, 3:05:11 PM12/16/04
to
Keith Dart wrote:
> What I do is set Python's sys.ps1 variable to something else. I have a
> module called "interactive" that I import implicitly by shell alias:
>
> py='python -i -c '\''import interactive'\'
>
> Which, among other things, sets the prompt to "Python> "

You can do the same thing using a PYTHONSTARTUP file - see
http://docs.python.org/tut/node4.html#SECTION004240000000000000000

You can change the prompts with
import sys
sys.ps1 = ' >>> '
sys.ps2 = ' ... '

Kent

Steven Bethard

unread,
Dec 16, 2004, 4:36:37 PM12/16/04
to
Kent Johnson wrote:
> You can do the same thing using a PYTHONSTARTUP file - see
> http://docs.python.org/tut/node4.html#SECTION004240000000000000000
>
> You can change the prompts with
> import sys
> sys.ps1 = ' >>> '
> sys.ps2 = ' ... '

Very cool. I didn't know about this. Does anyone know how to make it
work with Pythonwin[1]? (Obviously, I can type the above in manually
every time, but I'd much rather have Pythonwin do this automatically for
me.)

Steve

[1] I'd do my example code at the command prompt, but I can't live
without copy-paste. ;)

Fernando Perez

unread,
Dec 16, 2004, 6:51:23 PM12/16/04
to pytho...@python.org
Kent Johnson wrote:

<blatant plug>

You might want to look at ipython:

http://ipython.scipy.org,

which provides you automatically with these prompts:

In [1]: for i in range(2):
...: print i,
...:
0 1

In [2]: 99*2
Out[2]: 198

In [3]: _2+1
Out[3]: 199

As a curiosity, ipython was actually born as a sys.ps1/2 hack, by assigning to
these objects whose __repr__ would give numbered prompts with results caching.
These days it's a full-blown pure python interpreter, not a $PYTHONSTARTUP
customization anymore, but it's an interesting little historical curiosity.
Especially if you start going very far with interactive customizations, you
might not want to rewrite all of ipython's 15K lines of code :)

</blatant plug>

Cheers,

f

Keith Dart

unread,
Dec 17, 2004, 12:47:28 AM12/17/04
to
Fernando Perez wrote:

> <blatant plug>
>
> You might want to look at ipython:
>
> http://ipython.scipy.org,
>
>

> </blatant plug>
>

I did just recently install that. It looks very nice. Would make a great
interactive prompt for an IDE, as well.

--
\/ \/
(O O)
-- --------------------oOOo~(_)~oOOo----------------------------------------
Keith Dart <kd...@kdart.com>

vcard: <http://www.kdart.com/~kdart/kdart.vcf>
public key: ID: F3D288E4 URL: <http://www.kdart.com/~kdart/public.key>
============================================================================

Keith Dart

unread,
Dec 17, 2004, 12:47:27 AM12/17/04
to Fernando Perez, pytho...@python.org
Fernando Perez wrote:

> <blatant plug>
>
> You might want to look at ipython:
>
> http://ipython.scipy.org,
>
>

> </blatant plug>
>

I did just recently install that. It looks very nice. Would make a great
interactive prompt for an IDE, as well.

--

\/ \/
(O O)
-- --------------------oOOo~(_)~oOOo----------------------------------------
Keith Dart <kd...@kdart.com>

aleks...@hotmail.com

unread,
Dec 17, 2004, 7:55:43 AM12/17/04
to
Thought you might enjoy my super-small flatten function: (though google
groups seems to be munging my whitespace today)

def flatten(d):
"flatten([[[1,[2,3],[4,5]],6],[7]])==[1,2,3,4,5,6,7]"
return reduce(lambda a,b:a+b,[(type(x) in (list, tuple) \
and flatten(x) or [x]) for x in d])

Kent Johnson

unread,
Dec 17, 2004, 8:03:12 AM12/17/04
to
Steven Bethard wrote:
> Very cool. I didn't know about this. Does anyone know how to make it
> work with Pythonwin[1]? (Obviously, I can type the above in manually
> every time, but I'd much rather have Pythonwin do this automatically for
> me.)
>
> Steve
>
> [1] I'd do my example code at the command prompt, but I can't live
> without copy-paste. ;)

You can copy and paste from a Windows command prompt. It's a bit bizarre, but
- In the system menu for a command window, pick Properties
- On the Options tab, turn on Quick Edit mode
- Now you can copy and paste with right-click (!). If you have text selected, right-click will copy,
otherwise paste. It's a bit strange but it works.

I think it's wonderfully ironic that in Windows - which takes such pains to make everything keyboard
accessible - in a *command line* window, which is using keyboard input by its nature - you have to
use the mouse for copy and paste!!

Kent

Steven Bethard

unread,
Dec 17, 2004, 12:22:38 PM12/17/04
to
Kent Johnson wrote:
> You can copy and paste from a Windows command prompt. It's a bit
> bizarre, but
> - In the system menu for a command window, pick Properties
> - On the Options tab, turn on Quick Edit mode
> - Now you can copy and paste with right-click (!). If you have text
> selected, right-click will copy, otherwise paste. It's a bit strange but
> it works.

Yeah, I'm familiar with this -- all my command windows are enabled with
Quick Edit. =) The problem is that I can't then edit what I've
copy-pasted. I can, of course, copy a few lines, type in an edited
line, copy a few more lines, type in another edited line, etc., but this
gets tedious...

Sorry about not being clear about my problem!

STeve

Fernando Perez

unread,
Dec 17, 2004, 5:16:14 PM12/17/04
to pytho...@python.org
Keith Dart wrote:

> Fernando Perez wrote:
>
>> <blatant plug>
>>
>> You might want to look at ipython:
>>
>> http://ipython.scipy.org,
>>
>>
>> </blatant plug>
>>
>
> I did just recently install that. It looks very nice. Would make a great
> interactive prompt for an IDE, as well.

Glad you like it :) And yes, there are plans to clean it up so it can be
easily embedded into a full-blown IDE (as well as remaining available for
regular command-line use). This keeps on getting delayed by inevitable bug
fixes and my very limited time, but it will happen...

Best,

f

Bengt Richter

unread,
Dec 17, 2004, 10:53:52 PM12/17/04
to

Not true on NT4 at least:

Alt-Spacebar gets you the system menu
Follow with e then k which gets you in select mode

use arrow keys to move to top left of a box, or whole screen
(if there's more buffer than screen, arrows should cause scrolling
to access more)

hold shift key down and use arrow keys while continuing to hold
the shift key down to select a box of text (need not be at edges)
this can also scroll through buffer as necessary to select more than can
be visible at one time. Just keep holding down shift.

press enter to capture box of text to clipboard

paste as usual with ctrl-v ins some apps, shift-insert in vim (depending),
or paste back into the dos window with Alt-spacebar e p

Regards,
Bengt Richter

Scott David Daniels

unread,
Dec 20, 2004, 1:45:20 PM12/20/04
to
Bengt Richter wrote:
> Not true on NT4 at least:
> Alt-Spacebar gets you the system menu ....
> paste into the dos window with Alt-spacebar e p
Thanks immensely for this -- I love it.

--Scott David Daniels
Scott....@Acm.Org

Steven Bethard

unread,
Dec 27, 2004, 3:10:39 AM12/27/04
to
I wrote:
> Kent Johnson wrote:
>
>> You can do the same thing using a PYTHONSTARTUP file - see
>> http://docs.python.org/tut/node4.html#SECTION004240000000000000000
>>
>> You can change the prompts with
>> import sys
>> sys.ps1 = ' >>> '
>> sys.ps2 = ' ... '
>
>
> Very cool. I didn't know about this. Does anyone know how to make it
> work with Pythonwin[1]?

Solved my own problem here. For anyone else out there using PythonWin,
the solution that worked for me is to put the following (or whatever
customizations you want) in a sitecustomize.py somewhere on my PYTHONPATH:

import sys
sys.ps1 = 'py> '
sys.ps2 = '... '

PythonWin (as well as my Command Prompt python) now has the above prompts.

Steve

0 new messages