for-loop-if like list comps have?
mylist = ['apple', 'banana', 'orange', 'grapefruit'] # Why is this okay... for item in [x for x in mylist if 'p' in x]: print(item) # But this isn't? for item in mylist if 'p' in item: SyntaxError: invalid syntax # Instead you have to do another nesting level.. for item in mylist: if 'p' in item: print(item) # Or another way. for item in mylist: if 'p' not in item: continue print(item) ...And there is 'filter', 'lambdas', and whatever else to achieve the same result. But the list comprehension is already closely related to a for-loop, and it seems natural to go from: [x for x in mylist if x] to: for x in mylist if x: Just an idea, sorry if it has been mentioned before. -- \¯\ /¯/\ \ \/¯¯\/ / / Christopher Welborn (cj) \__/\__/ / cjwelborn at live·com \__/\__/ http://welbornprod.com
On Fri, Mar 14, 2014 at 09:07:18PM -0500, Christopher Welborn wrote:
mylist = ['apple', 'banana', 'orange', 'grapefruit']
# Why is this okay... for item in [x for x in mylist if 'p' in x]: print(item)
# But this isn't? for item in mylist if 'p' in item: SyntaxError: invalid syntax
This suggestion has been made, oh, a million times -- not that I would ever exaggerate... *wink* -- and has been rejected each time. Personally, I don't think it gains you too much, all you save is one line and one nesting level, and if you're nested so deeply that this becomes important, your code is probably in desperate need of refactoring. The downside includes additional complication. It's one more thing for people to learn. Not only do you have to learn that there are two independent features, the for-statement and the if-statement, which being independent can be combined however you like: # 1 for x in seq: if cond: ... #2 if cond: for x in seq: ... but now you also have to learn a *third* form: for x in seq if cond: ... and learn that it is the same as #1 above rather than #2 above. And that there *isn't* a fourth form: if cond for x in seq: ... or other combinations like: while x if cond: if cond while x: if cond try: for x try: for x if y try: etc. The way statements work in Python is that you combine them by using a new line and starting a new block, not by having special syntactic forms for each combination. List comprehensions are different, because they don't create a new block, and they are an expression not a statement. -- Steven
On 03/14/2014 09:37 PM, Steven D'Aprano wrote:
This suggestion has been made, oh, a million times -- not that I would ever exaggerate... *wink* -- and has been rejected each time.
Oops, I wouldn't have mentioned it if I had known.
or other combinations like:
while x if cond: if cond while x: if cond try: for x try: for x if y try:
Yeh I could see things getting out of hand if all of those were added. You both have made good points. Thank you. -- \¯\ /¯/\ \ \/¯¯\/ / / Christopher Welborn (cj) \__/\__/ / cjwelborn at live·com \__/\__/ http://welbornprod.com
On Mar 14, 2014, at 19:07, Christopher Welborn
mylist = ['apple', 'banana', 'orange', 'grapefruit']
# Why is this okay... for item in [x for x in mylist if 'p' in x]: print(item)
# But this isn't? for item in mylist if 'p' in item: SyntaxError: invalid syntax
# Instead you have to do another nesting level.. for item in mylist: if 'p' in item: print(item)
# Or another way. for item in mylist: if 'p' not in item: continue print(item)
...And there is 'filter', 'lambdas', and whatever else to achieve the same result. But the list comprehension is already closely related to a for-loop, and it seems natural to go from: [x for x in mylist if x] to: for x in mylist if x:
Just an idea, sorry if it has been mentioned before.
In a listcomp, each for or if is a separate clause, and they can be nested any way you want (except for the restriction that the first clause has to be a for). So, you can do this: [x for xs in xss for x in xs] [x for x in xs if x if x-1] [x for xs in xss if xs for x in xs if x] Should you be able to write all of those as one-liner statements? And this isn't just a weird quirk of syntax; each clause is conceptually exactly the same as a nested statement (except for some minor differences with the first one); that's how comprehensions are defined in the language reference. Not all languages do comprehensions this way; Clojure, Racket, etc. have only for loop clauses in their comprehensions, but every for loop clause has an optional if phrase. Which would make your translation obviously right, instead of wrong for a hard to notice reason. (And it would make comprehensions slightly easier to explain. And it would also make it easier to add things like a while phrase, which people keep asking for.) But that would be a pretty big change for Python at this point.
On 03/14/2014 09:43 PM, Andrew Barnert wrote:
[x for xs in xss for x in xs] [x for x in xs if x if x-1] [x for xs in xss if xs for x in xs if x]
Should you be able to write all of those as one-liner statements?
Fair enough. No I wouldn't like any of those, but thanks for making things clearer for me. -- \¯\ /¯/\ \ \/¯¯\/ / / Christopher Welborn (cj) \__/\__/ / cjwelborn at live·com \__/\__/ http://welbornprod.com
participants (3)
-
Andrew Barnert
-
Christopher Welborn
-
Steven D'Aprano