473,399 Members | 3,302 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Proposal: [... for ... while cond(x)]

I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]

which would be equivalent to

list(itertools.takewhile(cond, xs))

+ Since Python favors list comprehensions over map, filter, and reduce,
this would be the preferred way to do this
+ "Takewhile operations" occur often, at least for me
+ I don't think it would break any existing syntax

An analogous syntax for dropwhile would be nice, but I can't think of
one.

This is not a PEP because it's a very simple idea and probably not just
anyone (read: me) can write and submit one. If there has been a PEP for
this, I've missed it; if not, it would be nice if someone wrote one.

Discuss.

Aug 6 '06 #1
12 1698
Eighty wrote:
I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]

which would be equivalent to

list(itertools.takewhile(cond, xs))
What would this syntax offer that:

[x for x in takewhile(cond, xs)]

doesn't currently offer? (Apart, that is, from saving you 3 characters of
typing)
Aug 6 '06 #2

Duncan Booth wrote:
Eighty wrote:
I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]

which would be equivalent to

list(itertools.takewhile(cond, xs))

What would this syntax offer that:

[x for x in takewhile(cond, xs)]

doesn't currently offer? (Apart, that is, from saving you 3 characters of
typing)
The same thing that [f(x) for x in xs] offers that map(f, xs) doesn't,
and the same thing that [x for x in xs if f(x)] offers that filter(f,
xs) doesn't. It's more "pythonic". You can use an expression for cond
instead of a lambda.

Aug 6 '06 #3
Eighty wrote:
>
Duncan Booth wrote:
>Eighty wrote:
I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]

which would be equivalent to

list(itertools.takewhile(cond, xs))

What would this syntax offer that:

[x for x in takewhile(cond, xs)]

doesn't currently offer? (Apart, that is, from saving you 3
characters of typing)

The same thing that [f(x) for x in xs] offers that map(f, xs) doesn't,
and the same thing that [x for x in xs if f(x)] offers that filter(f,
xs) doesn't. It's more "pythonic". You can use an expression for cond
instead of a lambda.

No, the list comprehension lets you write an expression directly avoiding a
function call, and it also allows you to add in a condition which can be
used to filer the sequence. Your proposal adds nothing.
Aug 6 '06 #4
On Sun, 06 Aug 2006 18:59:39 +0000 (GMT)
Duncan Booth <du**********@invalid.invalidwrote:

# I suggest a new extension of the list comprehension syntax:
#
# [x for x in xs while cond(x)]
#
# which would be equivalent to
#
# list(itertools.takewhile(cond, xs))
#>
#What would this syntax offer that:
#>
# [x for x in takewhile(cond, xs)]
#>
#doesn't currently offer?
#
# The same thing that [f(x) for x in xs] offers that map(f, xs) doesn't,
# and the same thing that [x for x in xs if f(x)] offers that filter(f,
# xs) doesn't. It's more "pythonic". You can use an expression for cond
# instead of a lambda.
#
#No, the list comprehension lets you write an expression directly
#avoiding a function call, and it also allows you to add in a
#condition which can be used to filer the sequence.

I am not sure if I understand you correctly, but... Does it?
>>a = [0,1,2,3,7,8,9]
[x for x in takewhile(lambda x: x in a, range(10))]
[0, 1, 2, 3]
>>[x for x in takewhile(x in a, range(10))]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'bool' object is not callable

Did I miss something? Notice that using "if" gives different result:
>>[x for x in range(10) if x in a]
[0, 1, 2, 3, 7, 8, 9]

#Your proposal adds nothing.

Well, I am not sure how useful the proposal really is, but it seems to
add *something* if it would allow for things like:
[x for x in range(10) while x in a]

--
Best wishes,
Slawomir Nowaczyk
( Sl***************@cs.lth.se )

Women who seek to be equal to men lack ambition.

Aug 6 '06 #5
No, the list comprehension lets you write an expression directly avoiding a
function call, and it also allows you to add in a condition which can be
used to filer the sequence. Your proposal adds nothing.
It does. Consider this:

whatever = [x for x in xrange(1000000000) while x < 10]
That would run only in a splitsecond of what the whole listcomp would.
Yet I still fail to see that this is a really useful use-case. takewhile
is easily abstracted away as map and reduce and filter are using lambda
- which I'm a modest supporter of.

But functions that are monotonic such that the takewhile really offers a
advantage over the much more general listcomp + if are IMHO way to
seldom to justify a new syntax.

The overall complexity is still O(n).

Regards,

Diez
Aug 7 '06 #6
Diez B. Roggisch wrote:
>No, the list comprehension lets you write an expression directly
avoiding a function call, and it also allows you to add in a
condition which can be used to filer the sequence. Your proposal adds
nothing.

It does. Consider this:

whatever = [x for x in xrange(1000000000) while x < 10]
That would run only in a splitsecond of what the whole listcomp would.
Except that the comparable listcomp today is:

whatever = [x for x in takewhile(lambda x: x < 10, xrange(1000000000))]

which also runs in a split second.

Actually, the OP was correct, it does add something: it removes the need
for a function or lambda in the takewhile just as the original listcomp
removes a function or lambda compared with the map version.
Aug 7 '06 #7
Slawomir Nowaczyk wrote:
#No, the list comprehension lets you write an expression directly
#avoiding a function call, and it also allows you to add in a
#condition which can be used to filer the sequence.

I am not sure if I understand you correctly, but... Does it?
>>>a = [0,1,2,3,7,8,9]
[x for x in takewhile(lambda x: x in a, range(10))]
[0, 1, 2, 3]
>>>[x for x in takewhile(x in a, range(10))]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'bool' object is not callable

Did I miss something?
Yes, you missed out a lambda (so I was wrong, your suggestion would
actually gain you more than 3 characters of typing)

Try:
>>a = [0,1,2,3,7,8,9]
[x for x in takewhile(lambda x:x in a, range(10))]
[0, 1, 2, 3]

For this particular expression you could also write:
>>[x for x in takewhile(a.__contains__, range(10))]
[0, 1, 2, 3]

or with Python 2.5 we can avoid referencing __contains__ with the following
variant:
>>from itertools import takewhile
from functools import partial
from operator import contains
a = [0,1,2,3,7,8,9]
[x for x in takewhile(partial(contains,a), range(10))]
[0, 1, 2, 3]
>>>
Aug 7 '06 #8
Duncan Booth <du**********@invalid.invalidwrote in
news:Xn*************************@127.0.0.1:
Diez B. Roggisch wrote:
>>No, the list comprehension lets you write an expression directly
avoiding a function call, and it also allows you to add in a
condition which can be used to filer the sequence. Your proposal
adds
>>nothing.

It does. Consider this:

whatever = [x for x in xrange(1000000000) while x < 10]
That would run only in a splitsecond of what the whole listcomp
would.
>
Except that the comparable listcomp today is:

whatever = [x for x in takewhile(lambda x: x < 10, xrange
(1000000000))]
>
which also runs in a split second.

Actually, the OP was correct, it does add something: it removes the
need
for a function or lambda in the takewhile just as the original
listcomp
removes a function or lambda compared with the map version.
Consider how it would be if the situation were reversed, and
whatever = [x for x in xrange(1000000000) while x < 10] was the
convention today. What advantage would there be to replacing it with
whatever = [x for x in takewhile(lambda x: x < 10, xrange(1000000000))]?

As a newcomer to Python, I'd find the first syntax far more readily
graspable, and I'd have to wonder why I'd ever need takewhile and lambda
just to do what appears to be straightforward conditioning of a loop.

I'm not a newcomer to Python, and I wonder about that anyway.

I also note this, using Python 2.4.2 on win32:
>>whatever = [x for x in takewhile(lambda x: x < 10, xrange
(1000000000))]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'takewhile' is not defined

So in addition to the two functions, I need an import statement. It
looks like the argument can certainly be made that simplifying the
syntax and lightening the call load bring some advantage to the table.
There are other arguments to be made against the proposed syntax, I'm
sure.

--
rzed

Aug 7 '06 #9

Eighty wrote:
I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]

which would be equivalent to

list(itertools.takewhile(cond, xs))

+ Since Python favors list comprehensions over map, filter, and reduce,
this would be the preferred way to do this
+ "Takewhile operations" occur often, at least for me
+ I don't think it would break any existing syntax

An analogous syntax for dropwhile would be nice, but I can't think of
one.

This is not a PEP because it's a very simple idea and probably not just
anyone (read: me) can write and submit one. If there has been a PEP for
this, I've missed it; if not, it would be nice if someone wrote one.

Discuss.
So does no one have a comment on this? The one objection I can come up
with is that this would change the set builder notation semantics too
much, but since the iteration order in a list comprehension is already
well defined, I don't think that would be the case. However, for this
reason, it wouldn't fit in a dict comprehension, if that would ever be
made, perhaps making the syntax inconsistent?

Aug 8 '06 #10

"Eighty" <ei*****@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com...
>
Eighty wrote:
>I suggest a new extension of the list comprehension syntax:

[x for x in xs while cond(x)]
This does not work.

e(x) for x in xs if cond(x)

is an abbreviation of

for x in xs:
if cond(x)
yield e(x)

and similarly with more for and if clauses,
whereas the analogous expansion of your proposal

for x in xs:
while cond(x):
yield e(x)

is an infinite loop and not at all what you mean.
>which would be equivalent to

list(itertools.takewhile(cond, xs))
And what would

x for x in xs while cond(x) if blah(x)
x for x in xs if blah(x) while cond(x)
x*y for x in xs while cond(x) for y in ys

mean? The ability to mix and match clauses after the first for clause is
an important part of comprehension syntax.
>+ "Takewhile operations" occur often, at least for me
So keep using the function provided. I am pretty sure takewhile is rare
for most other people.
So does no one have a comment on this?
Ain't gonna happen.
The one objection I can come up with
is that this would change the set builder notation semantics too much
Yes, to the point where you are hijacking the syntax, for no useful gain,
more than extending it ;-).

Terry Jan Reedy

Aug 8 '06 #11

Terry Reedy wrote:
whereas the analogous expansion of your proposal

for x in xs:
while cond(x):
yield e(x)

is an infinite loop and not at all what you mean.
You're right. The syntax is ambiguous. I agree it's not a good idea,
now. :)
x for x in xs while cond(x) if blah(x)
x for x in xs if blah(x) while cond(x)
x*y for x in xs while cond(x) for y in ys
These wouldn't be a problem.
"... for x in xs while cond(x) ..." would be transformed into "... for
x in takewhile(cond, xs) ..."
which could be applied to an if thingy if you first transform
"... for x in xs if cond(x) ..." into "... for x in filter(cond, xs)
....".

Aug 8 '06 #12
Eighty:
So does no one have a comment on this?
Similar proposals have appeared before (such as on python-dev about
a year ago) and haven't attracted much positive comment. The benefits
appear to be small compared to the cost of making the language larger.
You could try the formal route of writing a PEP so that a detailed
proposal and its reasons for (probable) rejection would be available for
others.

Neil
Aug 8 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Adal Chiriliuc | last post by:
I think a function similar to the one below should be added to the builtin module: def boolselect(condition, trueresult, falseresult): if condition: return trueresult else: return falseresult...
11
by: Paul Rubin | last post by:
I frequently find myself writing stuff like # compute frob function, x has to be nonnegative x = read_input_data() assert x >= 0, x # mis-use of "assert" statement frob = sqrt(x)...
2
by: Guido van Rossum | last post by:
Robert and Python-dev, I've read the J2 proposal up and down several times, pondered all the issues, and slept on it for a night, and I still don't like it enough to accept it. The only reason...
15
by: Ralf W. Grosse-Kunstleve | last post by:
****************************************************************************** This posting is also available in HTML format: http://cci.lbl.gov/~rwgk/python/adopt_init_args_2005_07_02.html...
4
by: wkaras | last post by:
I would like to propose the following changes to the C++ Standard, the goal of which are to provide an improved ability to specify the constraints on type parameters to templates. Let me say from...
0
by: jygoh3 | last post by:
ENCYCLOPEDIA OF MOBILE COMPUTING & COMMERCE CALL FOR SHORT ARTICLES Proposal Deadline: 15 Nov 2005 (Extended)
47
by: Pierre Barbier de Reuille | last post by:
Please, note that I am entirely open for every points on this proposal (which I do not dare yet to call PEP). Abstract ======== This proposal suggests to add symbols into Python. Symbols...
28
by: kaferro | last post by:
What is the safest way to make an argv comparison? The code below works. #include <iostream> #include <string> using namespace std; int main(int argc, char *argv) {
56
by: Adem | last post by:
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" The C++ Standard (ISO/IEC 14882, Second edition, 2003-10-15) says under...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.