*Hi, I am a graduating Berkeley student that loves python and would like to propose an enhancement to python. My proposal introduces a concept of slicing generator. For instance, if one does x[:] it returns a list which is a copy of x. Sometimes programmers would want to iterate over a slice of x, but they do not like the overhead of constructing another list. Instead we can create a similar operator that returns a generator. My proposed syntax is x(:). The programmers are of course able to set lower, upper, and step size like the following. x(1::-1) This would make code much cleaner in a lot of instances, one example lets say we have a very large list x and we want to sum all the numbers but the last 20, and we only want to loop through the even indices. We would have to do something like this. sum(x[:-20:2]) or we can do a workaround to save space for time and do something like this. sum( value for i, value in enumerate(x) if i < -20 and not i % 2 ) But with my proposal we are able do the following. sum(x(:-20:2)) Which affords space without sacrificing expressiveness. For another example lets say we have a problem that we want to check a condition is true for every pairwise element in a list x. def allfriends(x): for i in range(len(x)): for j in range(i+1, len(x)): if not friends(x[i], x[j]): return False return True A more pythonic way is to actually loop through the values instead of the indices like this. def allfriends(x): for i, a in enumerate(x): for j, b in enumerate(x[i+1:]): if not friends(a, b): return False return True This however bring a lot of overhead because we have to construct a new list for every slice call. With my proposal we are able to do this. def allfriends(x): for i, a in enumerate(x): for j, b in enumerate(x(i+1:)): if not friends(a, b): return False return True This proposal however goes against one heuristic in the zen of python, namely “Special cases aren’t special enough to break the rules.” The way that the proposal breaks this rule is because the syntax x(:), uses a function call syntax but would be a special case here. I chose using parenthesis because I wanted this operation to be analogous to the generator syntax in list comprehensions. ListGeneratorsComprehension[ x for x in L ]( x for x in L )SlicingL[a:b:c] L(a:b:c) Tell me what you guys think. Thanks!*
On 03/21/2012 07:39 PM, Huan Do wrote:
*Hi,
I am a graduating Berkeley student that loves python and would like to propose an enhancement to python. My proposal introduces a concept of slicing generator. For instance, if one does x[:] it returns a list which is a copy of x. Sometimes programmers would want to iterate over a slice of x, but they do not like the overhead of constructing another list. Instead we can create a similar operator that returns a generator. My proposed syntax is x(:). The programmers are of course able to set lower, upper, and step size like the following.
x(1::-1)
This would make code much cleaner in a lot of instances, one example lets say we have a very large list x and we want to sum all the numbers but the last 20, and we only want to loop through the even indices.
We would have to do something like this.
sum(x[:-20:2])
or we can do a workaround to save space for time and do something like this.
sum( value for i, value in enumerate(x) if i < -20 and not i % 2 )
But with my proposal we are able do the following.
sum(x(:-20:2))
Which affords space without sacrificing expressiveness.
For another example lets say we have a problem that we want to check a condition is true for every pairwise element in a list x.
def allfriends(x):
for i in range(len(x)):
for j in range(i+1, len(x)):
if not friends(x[i], x[j]):
return False
return True
A more pythonic way is to actually loop through the values instead of the indices like this.
def allfriends(x):
for i, a in enumerate(x):
for j, b in enumerate(x[i+1:]):
if not friends(a, b):
return False
return True
This however bring a lot of overhead because we have to construct a new list for every slice call. With my proposal we are able to do this.
def allfriends(x):
for i, a in enumerate(x):
for j, b in enumerate(x(i+1:)):
if not friends(a, b):
return False
return True
This proposal however goes against one heuristic in the zen of python, namely “Special cases aren’t special enough to break the rules.” The way that the proposal breaks this rule is because the syntax x(:), uses a function call syntax but would be a special case here. I chose using parenthesis because I wanted this operation to be analogous to the generator syntax in list comprehensions.
List Generators Comprehension [ x for x in L ] ( x for x in L ) Slicing L[a:b:c] L(a:b:c)
Tell me what you guys think.
Thanks!*
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/animelovin%40gmail.com
Hi, I'm not sure i get it.. Assuming your PEP is accepted, what should happens then to the lambda op and standard function calls ? Or Is this merely another case of metaprogramming, which obviously should not be confused with languages such as lisp? Thank you, Etienne
Huan Do wrote:
*Hi,
I am a graduating Berkeley student that loves python and would like to propose an enhancement to python. My proposal introduces a concept of slicing generator. For instance, if one does x[:] it returns a list which is a copy of x. Sometimes programmers would want to iterate over a slice of x, but they do not like the overhead of constructing another list. Instead we can create a similar operator that returns a generator. My proposed syntax is x(:). The programmers are of course able to set lower, upper, and step size like the following.
x(1::-1)
The biggest problem with your proposal is that generators don't remember what they have already yielded, so x(:) != x(:) # first time gets everything, second time gets nothing ~Ethan~
@Ethan Furman each call to x(:) would return a different iterator, so both sides will have their own information about where they are. Also it is the case that checking for equality of generators does not make the generators to expand out, so checking for equality becomes to checking if they are the same generator object. The following example shows this Python3
(x for x in range(10)) == (x for x in range(10)) False
@Etienne "lambda" is a keyword and would get captured by the lexer, so this should conflict with adding the grammar that would make this work. This is different than function calls because currently arguments of function calls cannot have ":", causing `x(:)` to be a syntax error. The grammar that would have to be added would be mutually exclusive from current functionality. @Victor I was not completely familiar with itertools but itertools.islice() seems to have the functionality that I propose. It is great that there already exist a solution that does not change python's syntax. Unless anyone wants to pursue this proposal I will drop it next week. Thanks for your feedback guys On Wed, Mar 21, 2012 at 5:09 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
Huan Do wrote:
*Hi,
I am a graduating Berkeley student that loves python and would like to propose an enhancement to python. My proposal introduces a concept of slicing generator. For instance, if one does x[:] it returns a list which is a copy of x. Sometimes programmers would want to iterate over a slice of x, but they do not like the overhead of constructing another list. Instead we can create a similar operator that returns a generator. My proposed syntax is x(:). The programmers are of course able to set lower, upper, and step size like the following.
x(1::-1)
The biggest problem with your proposal is that generators don't remember what they have already yielded, so
x(:) != x(:) # first time gets everything, second time gets nothing
~Ethan~
On Thu, Mar 22, 2012 at 10:28 AM, Huan Do <doboy0@gmail.com> wrote:
I was not completely familiar with itertools but itertools.islice() seems to have the functionality that I propose. It is great that there already exist a solution that does not change python's syntax. Unless anyone wants to pursue this proposal I will drop it next week.
Just as a further follow-up on the recommended approach for making suggestions: for initial concepts like this one, the "python-ideas" mailing list is the preferred venue. It's intended for initial validation and refinement of suggestions to see if they're a reasonable topic for the main development list. Many ideas don't make it past the python-ideas stage (either because they have too many problems, they get redirected to a third party PyPI project, or existing alternatives are pointed out, as happened in this case). Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Thu, Mar 22, 2012 at 00:39, Huan Do <doboy0@gmail.com> wrote:
Tell me what you guys think.
I don't really want to add more things to the language, so I hate to say this: It makes sense to me. However, the syntax is very close to the syntax for function annotations. But that's when defining, and this is when calling, so it might work anyway, I don't have the knowledge necessary to know. So put it up on python-ideas. I'm not on that list, but people who know more about this are, so they can tell you if this is feasible or not and if it is a good idea or not. //Lennart
participants (6)
-
Ethan Furman -
Etienne Robillard -
Huan Do -
Lennart Regebro -
Nick Coghlan -
Victor Stinner