i was wondering if there is a syntax alike:
for i in range(10) if i > 5:
print i
equivalent to
for i in (for i in range(10) if i>5):
print i
sebastien
AFAIK, no syntax fo that. But the standard syntax is not too
different:
for i in range(0):
if i > 5 : print i
Or you can use itertools.ifilter:
for i in itertools.ifilter( lambda x: x > 5, range(10) ):
print i
Or, if you define a function corresponding to the loop body, you could
do something like:
map( print, (i for i in range(10) if i> 5 )) # only works if print is
a function
Ciao
----
FB
> Hi,
>
> i was wondering if there is a syntax alike:
>
> for i in range(10) if i > 5:
> print i
You can write
for i in filter(lambda i: i > 5, range(10)):
print i
but
for i in range(10):
if i > 5:
print i
it' better readable, and
for i in range(6,10):
print i
it's event better.
How about using a generator expression instead of a list?
for i in (x for x in range(10) if x > 5):
print i
-John
Indeed, but we could have the same syntax than for generators but
directly in the for statement as in
for variable in generator if condition:
body
Is there a special reason for not doing so ? A rejected PEP ?
I just found the same thread on the python ideas group at
http://mail.python.org/pipermail/python-ideas/2009-April/004278.html
sorry for reposting
It's not been added since it's completely unnecessary (see the several
alternatives already presented by others).
There have been a few other mailinglist threads on adding essentially
the same syntax. None have proved fruitful.
Cheers,
Chris
--
http://blog.rebertia.com
> On Aug 23, 6:18 pm, John Posner <jjpos...@optimum.net> wrote:
[ ... ]
>> How about using a generator expression instead of a list?
>>
>> for i in (x for x in range(10) if x > 5):
>> print i
>>
>> -John
>
> Indeed, but we could have the same syntax than for generators but
> directly in the for statement as in
> for variable in generator if condition:
> body
>
> Is there a special reason for not doing so ? A rejected PEP ?
Well, the Zen of Python does say
There should be one-- and preferably only one --obvious way to do it.
Beyond that, I refer you to Gerald M. Weinberg's _The Psychology of Computer
Programming_, specifically chapters 11 and 12, about Programming Languages,
and their design.
The proposal creates an case where one particular pair of syntactic
constructs can be mooshed together. OK for them, but everything else
becomes an exception; what about
while a==c if b != d:
why not
if b != d while a==c:
or
for a in range(7) if os.name == 'posix':
It winds up burdening the programmers with remembering which constructs are
and which are not mooshable. Weinberg gave an example: FORTRAN had some
stringent rules for what expressions were and were not allowed as array
subscripts. The result was that many programmers couldn't remember all the
rules, and often avoided using legal forms, having forgotten they were
legal.
Maybe the line was already crossed when list comprehensions came into being,
still, the damage is localized in a particular context: building a list. It
isn't out creating wild options in the program control flow at large.
Mel.
what about :
for i in range(6, 10):
print i
<g>
More seriously:
On Aug 23, 11:02 pm, Chris Rebert <c...@rebertia.com> wrote:
> --http://blog.rebertia.com- Hide quoted text -
>
> - Show quoted text -
Tx Chris for your reply !
i am still a bit puzzle by the following.
I read in http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Generators
"""Python 3.0 unifies all collection types by introducing dict and set
comprehensions, similar to list comprehensions:
>>> [ n*n for n in range(5) ] # regular list comprehension
[0, 1, 4, 9, 16]
>>>
>>> { n*n for n in range(5) } # set comprehension
{0, 1, 4, 16, 9}
>>>
>>> { n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
"""
and we can add to this list the quite similar syntax for generator
expressions.
On all these loop constructs, one can consistenly add filtering on a
condition by adding an "if ..." after the "for ... in ..." part (and
it looks to me difficult to argue, for instance, that we should not
allow filtering for dict comprehesion because we could get the same
result by some other construct)
If the "if ..." part after the "for ... in ..." is so much used in all
these list/dict/set comprehensions and in the generator expressions,
it makes sense to me to have it also for the "for as a statement"
syntax :
[ n*n for n in range(10) if n%3 == 0]
{ n*n for n in range(10) if n%3 == 0}
{ n: n*n for n in range(10) if n%3 == 0}
( n*n for n in range(10) if n%3 == 0)
for n in range(10) if n%3 == 0:
print n*n
In fact, we often see the list comprehension [ n*n for n in range(10)
if n%3 == 0] explained as being equivalent to
l = []
for n in range(10):
if n%3 == 0:
l.append(n)
We could as consistenly explain that the syntax
for n in range(10) if n%3==0:
body
means
for n in range(10):
if n%3==0:
body
This syntax has also the benefit of avoiding an extra level of
indentation (the one for the if) that bears no real meaning on a
structural level.
Maybe a PEP could do the job...
Sébastien
what would be the unambiguous meaning of any of these forms ?
they could be interesting but I do not understand them (yet!).
> or
>
> for a in range(7) if os.name == 'posix':
>
> It winds up burdening the programmers with remembering which constructs are
> and which are not mooshable. Weinberg gave an example: FORTRAN had some
> stringent rules for what expressions were and were not allowed as array
> subscripts. The result was that many programmers couldn't remember all the
> rules, and often avoided using legal forms, having forgotten they were
> legal.
indeed, the language features should stay as orthogonal as possible
(at least as a general rule)
>
> Maybe the line was already crossed when list comprehensions came into being,
> still, the damage is localized in a particular context: building a list. It
> isn't out creating wild options in the program control flow at large.
>
indeed and it proved to be very useful & successful.
one cannot recommend to mix all features together as a general rule
but using common sense and practice, we can have some exceptions that
are definitely worth.
> Mel.- Hide quoted text -
I'm sorry, I don't see what you mean about avoiding the extra level of
indentation? I can see a very real structural and logical distinction that
the if-block makes, and IMO it's a good thing that that needs to be set
apart.
--
Rami Chowdhury
"Never attribute to malice that which can be attributed to stupidity" --
Hanlon's Razor
408-597-7068 (US) / 07875-841-046 (UK) / 0189-245544 (BD)
So, what part of the statement does the "if" statement belong to;
particularly a concern considering this is valid python:
for x in y if y else z:
body
You can always do the following at the cost of 6 symbols, and the gain
of clarity:
for n in (x for x in y if y%3==0):
body
~G
>
> So, what part of the statement does the "if" statement belong to;
> particularly a concern considering this is valid python:
>
> for x in y if y else z:
> body
>
can this be done in list/set/dict comprehensions/generator
expressions ?
> You can always do the following at the cost of 6 symbols, and the gain
> of clarity:
>
> for n in (x for x in y if y%3==0):
> body
it is in fact precisely to avoid this sort of line:
for n in (x for x in y if x%3==0):
and have instead the (more readable IMO) line
for n in y if n%3==0:
with:
- 1 "for ... in ..." instead of 2 (where one is the repetition of the
other)
- no parentheses
- no extra technical variable with local binding to the expression
generator ('x')
it looks more pythonic to me but it is a personal taste.
>
> ~G
It's a statement, so anywhere you use a statement (such as in
generators and list comprehensions), it can exist. for ... in ... only
requires that the statement return an iterable, it doesn't matter what
statement you use to get there.
For example, the following is perfectly valid (if nonsensical - I
don't use ternary operators very often in my programming, so I don't
have many good examples of their use)
list = [x if x else y for x, y in iterable]
> it is in fact precisely to avoid this sort of line:
> for n in (x for x in y if x%3==0):
> and have instead the (more readable IMO) line
> for n in y if n%3==0:
> with:
> - 1 "for ... in ..." instead of 2 (where one is the repetition of the
> other)
> - no parentheses
> - no extra technical variable with local binding to the expression
> generator ('x')
> it looks more pythonic to me but it is a personal taste.
>
It doesn't feel clear to me, which is why I would have to disagree.
IIRC, these very filters are the main reason that list comprehensions,
and later one-line generators and dictionary comprehensions were
originally created: so you can filter the stream before acting on it.
One statement performs one action - very precise and understandable.
It's just my two cents, but I would not agree that adding a filter
keyword to for loops is required. Not when we have the filter
function, various types of comprehensions, and if statements which all
provide that very functionality.
~G
I never thought about this case...
Testing that in python 3.0, i see that
>>> [x for x in range(5) if False else range(10)]
SyntaxError: invalid syntax (<pyshell#17>, line 1)
>>> [x for x in (range(5) if False else range(10))]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
hence, to avoid the ambiguity you mentionned (that already exists with
list comprehensions), one can use the parenthesis. This minor
incompatibility is referenced in http://www.python.org/dev/peps/pep-0308/
> It doesn't feel clear to me, which is why I would have to disagree.
> IIRC, these very filters are the main reason that list comprehensions,
> and later one-line generators and dictionary comprehensions were
> originally created: so you can filter the stream before acting on it.
> One statement performs one action - very precise and understandable.
in my mind, I am thinking as you are but with 'loop' instead of
'stream'
"""so you can filter the 'loop' before acting on it. One statement
performs one action - very precise and understandable."""
and it doesn't look that dissimilar to your own reasoning.
>
> It's just my two cents, but I would not agree that adding a filter
> keyword to for loops is required. Not when we have the filter
> function, various types of comprehensions, and if statements which all
> provide that very functionality.
>
before having list comprehensions, we could also have said that
""" I would not agree that adding a 'list comprehension' feature is
required. Not when we have the filter
function, and the 'for+if' statements which all provide that very
functionality."""
How can unifying the "for ... in ..." statement with the "for ...
in ... if ..." syntax be detrimental ? It would be an inconsistence
less to remember, wouldn't it ?
cheers,
sebastien
>s> i am still a bit puzzle by the following.
>s> I read in http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Generators
>s> """Python 3.0 unifies all collection types by introducing dict and set
>s> comprehensions, similar to list comprehensions:
>>>>> [ n*n for n in range(5) ] # regular list comprehension
>s> [0, 1, 4, 9, 16]
>>>>>
>>>>> { n*n for n in range(5) } # set comprehension
>s> {0, 1, 4, 16, 9}
>>>>>
>>>>> { n: n*n for n in range(5) } # dict comprehension
>s> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>s> """
>s> and we can add to this list the quite similar syntax for generator
>s> expressions.
>s> On all these loop constructs, one can consistenly add filtering on a
>s> condition by adding an "if ..." after the "for ... in ..." part (and
>s> it looks to me difficult to argue, for instance, that we should not
>s> allow filtering for dict comprehesion because we could get the same
>s> result by some other construct)
You can also say:
[x+y for x in range(3) for y in range(4) if x < y]
If you want to write this as a loop you have to put the for's on
separate lines separated by colons, so why not the if also? Or would you
also like to have the for's on one line?
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: pi...@vanoostrum.org
indeed, we could have the for's on one line too. In fact, if you have
a double loop without any body that is specific to the outer loop, you
can merge the two lines. Similarly, if you have a loop with a if (ie
filter) without any body having to be executed outside the if, having
them on the same line is also clearer.
| for x in range(3):
| for x in range(3) for y in range(4):
| for y in range(4): could be written as
| body
| body
and
| for x in range(3):
| for x in range(3) if cond(x):
| if cond(x): could be written as
| body
| body
Such loops are in fact mentally just one loop over the cartesian
product (product set) of the two iterators or over the filter set of
the iterator respectively in these examples.
Moreover, for 'body' longer than a couple of lines, it is quite useful
to see immediately that there is no additional code that could be only
specific to the outher loop
ie, when writing all in one line, we can be sure that we do not have
this situation
| for x in range(3):
| for y in range(4):
| long body
| ...
| long body
| body related to outer loop
The naturalness of iteration in the various comprehensions and the
generator expressions can be smoothly extended to the standard code
iteration.
BTW, I noticed this inconsistency when, coming back to python after a
couple of weeks of no python programming, I started coding loops like
for obj in list_obj if obj.Size > 100:
print(obj)
and got an error message about syntax.
> --
> Piet van Oostrum <p...@cs.uu.nl>
> URL:http://pietvanoostrum.com[PGP 8DAE142BE17999C4]
> Private email: p...@vanoostrum.org- Hide quoted text -