I have an idea to improve the python language through the creation of a new and very readable function. ################# def ranlen(x): #range of length of x return range(len(x)) ################# This will be a simple to use and very readable way of creating ranges of indexes. I hope for this to become a new pythogenic way of writing code, especially because using range(leng(x)) is so essential when implementing various algorithms.
range(len(x)) is actually not that important. You probably need to be using enumerate() more often. On Fri, Apr 10, 2020 at 9:44 PM Chamoun Saoma <csaoma@gmail.com> wrote:
I have an idea to improve the python language through the creation of a new and very readable function.
################# def ranlen(x): #range of length of x return range(len(x)) #################
This will be a simple to use and very readable way of creating ranges of indexes. I hope for this to become a new pythogenic way of writing code, especially because using range(leng(x)) is so essential when implementing various algorithms. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FZYSNZ... Code of Conduct: http://python.org/psf/codeofconduct/
On Apr 10, 2020, at 12:46, Chamoun Saoma <csaoma@gmail.com> wrote:
I have an idea to improve the python language through the creation of a new and very readable function.
################# def ranlen(x): #range of length of x return range(len(x)) #################
I find this less readable. The abbreviation “ran” frequently means “random”; occasionally it means other things; I can’t think of any place where it means “range”. Also, not every one-liner needs to be a builtin. Look at the docs to see how short the list is. That’s important—not for performance or for making it easier to write alternative implementations (although it does help both of those a bit), but because there’s so little to learn and keep in your head as a novice, or as an occasional user who comes back to Python every few weeks while mostly working in Kotlin, or whatever. The things that are there are all hard to get right, or easy to get wrong, or need access to internals, or can benefit from a custom C-optimized implementation in CPython, etc. There’s no builtins for identity (a function that returns its argument), dummy (a function that takes any args and ignores them and does nothing), inc (a function that adds 1), etc., because when you do happen to need them, you (even a novice or an occasional Python user) can write them yourself without even slowing down. Finally, far from being essential to many algorithms, this is actually an antipattern, or at least a code smell—most code that’s doing it should be doing something else: for x in xs: dostuff(x) xs = [x+1 for x in xs] xs[:] = [x+1 for x in xs] for i, x in enumerate(xs): xs[i] = x+i for x, y in zip(xs, ys): print(x + y) … and so on. The alternatives are almost always clearer, more declarative, harder to get wrong, more general (e.g., working with all iterables rather than just sequences), and more efficient than what you would have written with a loop over the range. So, what about, say, the case where you explicitly want to loop over the first len(xs) of ys, and it should be an exception if ys is too short rather than stopping early so you can’t use zip? Sure. You could actually use zip_longest with a sentinel fillvalue, or other stuff from itertools—but sometimes maybe a loop over the range does make more sense. (There’s a reason those functions are in itertools rather than builtins.) But those are unusual cases. Which means they usually deserve to be called out. A change that makes it look less visible and less unusual would actually be counterproductive.
On 10/04/2020 20:31, Chamoun Saoma wrote:
This will be a simple to use and very readable way of creating ranges of indexes. I hope for this to become a new pythogenic way of writing code, especially because using range(leng(x)) is so essential when implementing various algorithms.
Since the introduction of enumerate() lo! these many moons ago, I find I almost never write range(len(x)) as a loop iterable. -- Rhodri James *-* Kynesim Ltd
On Sat, Apr 11, 2020 at 4:21 AM Rhodri James <rhodri@kynesim.co.uk> wrote:
Since the introduction of enumerate() lo! these many moons ago, I find I almost never write range(len(x)) as a loop iterable.
Out of curiosity, I just grepped about 300k lines of source: 234 - enumerate() in for loops 140 - zip() in for loops 12 - range(len()) in for loops About half of those 12 range uses are interfacing to extension modules that only provide an indexing interface to array-like data, so really no way around it... The remainder are in unit tests where we are just sloppily generating N-long test data values, where it could be better formulated, but no one cares enough to change it.
On Apr 11, 2020, at 08:22, Eric Fahlgren <ericfahlgren@gmail.com> wrote:
On Sat, Apr 11, 2020 at 4:21 AM Rhodri James <rhodri@kynesim.co.uk> wrote: Since the introduction of enumerate() lo! these many moons ago, I find I almost never write range(len(x)) as a loop iterable.
Out of curiosity, I just grepped about 300k lines of source:
234 - enumerate() in for loops 140 - zip() in for loops 12 - range(len()) in for loops
About half of those 12 range uses are interfacing to extension modules that only provide an indexing interface to array-like data, so really no way around it...
Actually, there is usually a way around it: just use enumerate/zip/etc. anyway. Any type for which sq_item/__getitem__ raises IndexError on the len-th index automatically is iterable, unless it goes out of its way to not be by implementing a tp_iter/__iter__ that raises, or does something pathological. And there are a few extension modules that explicitly implement a raising tp_iter, usually by mistake, but most don’t. In fact, this works even more generally than looping over range(len(x)). You don’t even have to provide tp_len/__len__ (e.g., because you’re presenting a dynamic Spam* array terminated by a sentinel value), and iteration still works.
participants (5)
-
Alex Hall
-
Andrew Barnert
-
Chamoun Saoma
-
Eric Fahlgren
-
Rhodri James