Hello Python Ideas, To quote the tutorial, "List comprehensions provide a concise way to create lists without resorting to use of map(), filter() and/or lambda.". There are a couple of constraints in the above definition that I feel could be overcome. For one thing, list comprehensions don't let you create immutable sequences (such as a tuple) by design. For another, it does not provide a concise alternative to reduce() function. To address both of the above, I'd like to introduce tuple comprehensions, which would work like so:
freshfruit = [' banana', ' loganberry ', 'passion fruit '] (weapon.strip() for weapon in freshfruit) ('banana', 'loganberry', 'passion fruit') import operator (operator.concat(_, weapon.strip()) for weapon in freshfruit) 'bananaloganberrypassion fruit'
As you can see, we use parenthesis instead of square brackets around the comprehension. In the first tuple comprehension, we create a true tuple with multiple items. This might a tad more efficient, not to mention less verbose, than applying the "tuple" function on top of a list comprehension. In the second tuple comprehension, we use a reduce() function (specifically operator.concat) to concatenate all of the fruit names. In particular, we use the "_" variable (for lack of a better name) to track the running outcome of the reduce() function. Best Regards, Karthick Sankarachary
Karthick Sankarachary schrieb am So, 09. Okt 2011, um 13:57:16 -0700:
(weapon.strip() for weapon in freshfruit) ('banana', 'loganberry', 'passion fruit')
This syntax is already taken for generator expressions. You can construct a tuple from the generator expression using tuple(weapon.strip() for weapon in freshfruit) Cheers, Sven
Steven D'Aprano <steve@pearwood.info> writes:
Your proposed syntax for tuple comprehensions:
(expr for x in iterable)
Syntax already used for generator expressions:
(expr for x in iterable)
More precisely, the parens are not part of the syntax for generator expressions. But the above syntax is a valid, paren-enclosed, generator expression; so the proposed syntax is indistinguishable from already-valid syntax that means something else in existing code. -- \ “We must respect the other fellow's religion, but only in the | `\ sense and to the extent that we respect his theory that his | _o__) wife is beautiful and his children smart.” —Henry L. Mencken | Ben Finney
On Tue, Oct 18, 2011 at 2:57 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
More precisely, the parens are not part of the syntax for generator expressions.
Yes they are. There's just an exception in the grammar to make it so that the *existing* parens that indicate a function call also count when a generator expression is the sole positional argument. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Nick Coghlan <ncoghlan@gmail.com> writes:
On Tue, Oct 18, 2011 at 2:57 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
More precisely, the parens are not part of the syntax for generator expressions.
Yes they are.
I had the impression that they could appear as a bare expression without parens. But the Python interpreter doesn't support that impression, so I guess I was wrong. Thanks for pointing it out. -- \ “We reserve the right to serve refuse to anyone.” —restaurant, | `\ Japan | _o__) | Ben Finney
On Tue, Oct 18, 2011 at 3:47 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
Nick Coghlan <ncoghlan@gmail.com> writes:
On Tue, Oct 18, 2011 at 2:57 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
More precisely, the parens are not part of the syntax for generator expressions.
Yes they are.
I had the impression that they could appear as a bare expression without parens. But the Python interpreter doesn't support that impression, so I guess I was wrong. Thanks for pointing it out.
You may have been thinking of yield expressions, where the parentheses aren't technically part of the syntax, but are still mandatory in a lot of places to avoid visual ambiguity. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Karthick Sankarachary <karthick.sankarachary@gmail.com> writes:
To address both of the above, I'd like to introduce tuple comprehensions, which would work like so:
freshfruit = [' banana', ' loganberry ', 'passion fruit '] (weapon.strip() for weapon in freshfruit) ('banana', 'loganberry', 'passion fruit') import operator (operator.concat(_, weapon.strip()) for weapon in freshfruit) 'bananaloganberrypassion fruit'
As you can see, we use parenthesis instead of square brackets around the comprehension.
That's already valid syntax. The parentheses are used around generator expressions in existing code. Since that's the case, why not just: tuple(weapon.strip() for weapon in freshfruit) if you want the generator expression turned into a tuple? -- \ “When people believe that they have absolute knowledge, with no | `\ test in reality, this [the Auschwitz crematorium] is how they | _o__) behave.” —Jacob Bronowski, _The Ascent of Man_, 1973 | Ben Finney
On 10/9/2011 4:57 PM, Karthick Sankarachary wrote:
There are a couple of constraints in the above definition that I feel could be overcome. For one thing, list comprehensions don't let you create immutable sequences (such as a tuple) by design.
To create an 'immutable' collection, one has to have all the items present from the beginning, along with their count. If the items are generated one at a time, they must be collected in a temporary mutable internal structure. So '(' comprehension ')' syntax like
(weapon.strip() for weapon in freshfruit)
was used to define and call an anonymous generator function, thus resulting in a generator. This is more flexible than making the result a tuple and in line with the Python 3 shift of emphasis toward iterators.
In the first tuple comprehension, we create a true tuple with multiple items. This might a tad more efficient, not to mention less verbose, than applying the "tuple" function on top of a list comprehension.
tuple(weapon.strip() for weapon in freshfruit) does little more than would have to be done anyway to produce a tuple. It is also a fairly rare need. A comprehension by its nature produces a homogeneous sequence as all items are produced from the same expression. In real use, tuples tend to be short and often heterogeneous. -- Terry Jan Reedy
On 10/09/2011 10:57 PM, Karthick Sankarachary wrote:
Hello Python Ideas,
To quote the tutorial, "List comprehensions provide a concise way to create lists without resorting to use of map(), filter() and/or lambda.".
There are a couple of constraints in the above definition that I feel could be overcome. For one thing, list comprehensions don't let you create immutable sequences (such as a tuple) by design. For another, it does not provide a concise alternative to reduce() function.
To address both of the above, I'd like to introduce tuple comprehensions, which would work like so:
freshfruit = [' banana', ' loganberry', 'passion fruit']
(weapon.strip() for weapon in freshfruit)
('banana','loganberry','passion fruit')
import operator (operator.concat(_, weapon.strip()) for weapon in freshfruit) 'bananaloganberrypassion fruit'
In addition to all previous remarks about the generator expression, what's wrong with the following?
import operator xs=['banana', 'loganberry', 'passion fruit'] reduce(operator.concat,(x.strip() for x in xs))
As you can see, we use parenthesis instead of square brackets around the comprehension.
In the first tuple comprehension, we create a true tuple with multiple items. This might a tad more efficient, not to mention less verbose, than applying the "tuple" function on top of a list comprehension.
In the second tuple comprehension, we use a reduce() function (specifically operator.concat) to concatenate all of the fruit names. In particular, we use the "_" variable (for lack of a better name) to track the running outcome of the reduce() function.
Best Regards, Karthick Sankarachary
On 2011-10-10, at 04:51 , Mathias Panzenböck wrote:
('banana','loganberry','passion fruit')
import operator (operator.concat(_, weapon.strip()) for weapon in freshfruit) 'bananaloganberrypassion fruit'
In addition to all previous remarks about the generator expression, what's wrong with the following?
import operator xs=['banana', 'loganberry', 'passion fruit'] reduce(operator.concat,(x.strip() for x in xs))
I'm guessing the issues (from the original mail) are that it does not benefit from the "concision" ascribed to comprehension (though that concision really is mostly when there isn't a mapping and/or filtering method readily available), and that `reduce` moved to `functools` in Python 3 And of course, for this precise expression you could just do this:
''.join(x.strip() for x in xs)
On Mon, Oct 17, 2011 at 7:57 PM, Christopher King <g.nius.ck@gmail.com> wrote: ..
reduce(operator.concat,(x.strip() for x in xs))
To long for something so simple
.. and how would tuple comprehensions help in this case? A shorter expression would be
''.join(x.strip() for x in xs)
For your data, .strip() seems redundant, so
''.join(xs)
would achieve the same result. Finally, a more realistic application would want to separate the data somehow:
','.join(xs)
Karthick Sankarachary wrote:
For one thing, list comprehensions don't let you create immutable sequences (such as a tuple) by design. For another, it does not provide a concise alternative to reduce() function.
There was a big discussion a while back about a syntax for reduction operations. The conclusion reached was that the concept of reduction has so many degrees of freedom that, beyond the very simple cases covered by the reduce() function, nothing is clearer than simply writing out the loop explicitly. -- Greg
Hi, All, As Masklinn pointed out, the issue is that there's no concise way to accumulate or compress an iterable without resorting to the use of the reduce() function. To answer Greg's point, it's not like list comprehensions cover all the cases allowed by the concept of mapping. There are cases, such as when the construction rule is too complicated, where comprehensions cannot be applied. Given that, why not explore the idea of if and how we can make (simple) reductions more readable. To me, the tricky part was resolving the ambiguity between a map and reduce expression in the comprehension. Given that the first argument to the reduce() function is the accumulated value, which is something that the map() function doesn't need, I felt that we could use that to make the distinction between the two in the comprehension. In particular, if the expression in the comprehension refers to the accumulated value (through the "_" variable), then it could treat it as a reduction as opposed to a mapping. Here's another example to illustrate the desired behavior, which basically adds a list of numbers (without resorting to the use of a reduce()):
numbers=[1,2,3,4,5] [_+number for number in numbers] 15
Just to clarify, we're just talking about some syntactic sugar here, nothing more, nothing less. Best Regards, Karthick Sankarachary On Mon, Oct 10, 2011 at 2:26 PM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Karthick Sankarachary wrote:
For one thing, list comprehensions don't let you create immutable sequences (such as a tuple) by design. For another, it does not provide a concise alternative to reduce() function.
There was a big discussion a while back about a syntax for reduction operations. The conclusion reached was that the concept of reduction has so many degrees of freedom that, beyond the very simple cases covered by the reduce() function, nothing is clearer than simply writing out the loop explicitly.
-- Greg
______________________________**_________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/**mailman/listinfo/python-ideas<http://mail.python.org/mailman/listinfo/python-ideas>
On Oct 10, 2011, at 1:36 PM, Karthick Sankarachary wrote:
Hi, All,
As Masklinn pointed out, the issue is that there's no concise way to accumulate or compress an iterable without resorting to the use of the reduce() function.
To answer Greg's point, it's not like list comprehensions cover all the cases allowed by the concept of mapping. There are cases, such as when the construction rule is too complicated, where comprehensions cannot be applied. Given that, why not explore the idea of if and how we can make (simple) reductions more readable.
…snip…
Here's another example to illustrate the desired behavior, which basically adds a list of numbers (without resorting to the use of a reduce()):
numbers=[1,2,3,4,5] [_+number for number in numbers] 15
Here's an even more readable version:
numbers=[1,2,3,4,5] total = sum(numbers)
I think the simple reductions (addition, concatenation) are already well covered by existing Python syntax. There's no need to try make sugar for anything more complicated than those two. Use a loop! -- Carl
On Tue, Oct 11, 2011 at 9:36 AM, Karthick Sankarachary <karthick.sankarachary@gmail.com> wrote:
Just to clarify, we're just talking about some syntactic sugar here, nothing more, nothing less.
And the increased cognitive burden in learning the language isn't worth it. Write a nice custom reduction function (like sum, any, all, min, max, etc) and feed it a generator expression. If you really want to argue the point, please read the following first: http://www.boredomandlaziness.org/2011/02/justifying-python-language-changes... http://www.boredomandlaziness.org/2011/02/status-quo-wins-stalemate.html And maybe this one as well: http://www.boredomandlaziness.org/2011/04/musings-on-culture-of-python-dev.h... (I guess those links may be the kind of thing that was being asked for recently when someone was wondering what kind of reaction to expect when posting suggestions to this list) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
participants (12)
-
Alexander Belopolsky
-
Ben Finney
-
Carl M. Johnson
-
Christopher King
-
Greg Ewing
-
Karthick Sankarachary
-
Masklinn
-
Mathias Panzenböck
-
Nick Coghlan
-
Steven D'Aprano
-
Sven Marnach
-
Terry Reedy