Repository navigation
Add operator.subscript as a convenience for creating slices #68567
Copy link
Copy link
Closed
Labels
3.7 (EOL)end of lifeend of lifeextension-modulesC modules in the Modules dirC modules in the Modules dirtype-featureA feature request or enhancementA feature request or enhancement
Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = <Date 2018-06-16.02:02:00.835>
created_at = <Date 2015-06-04.06:07:04.227>
labels = ['extension-modules', 'type-feature', '3.7']
title = 'Add operator.subscript as a convenience for creating slices'
updated_at = <Date 2018-07-20.00:08:42.343>
user = 'https://github.com/llllllllll'bugs.python.org fields:
activity = <Date 2018-07-20.00:08:42.343>
actor = 'vstinner'
assignee = 'none'
closed = True
closed_date = <Date 2018-06-16.02:02:00.835>
closer = 'rhettinger'
components = ['Extension Modules']
creation = <Date 2015-06-04.06:07:04.227>
creator = 'llllllllll'
dependencies = []
files = ['39614', '39615', '39775', '39792', '39902', '39904', '39906', '39907', '39913', '45471', '45473']
hgrepos = []
issue_num = 24379
keywords = ['patch']
message_count = 60.0
messages = ['244801', '244802', '244804', '244805', '244811', '244819', '244820', '244821', '245070', '245072', '245082', '245131', '245133', '245134', '245657', '245665', '245666', '245702', '246618', '246624', '246625', '246631', '246634', '246635', '246637', '246638', '246752', '247286', '247528', '247530', '248703', '248705', '248706', '248708', '248710', '253291', '253894', '253899', '253902', '254031', '256895', '272773', '272774', '272863', '280456', '280639', '280648', '280661', '280692', '280699', '280700', '280703', '280706', '280707', '280716', '280721', '319507', '319695', '321966', '321972']
nosy_count = 18.0
nosy_names = ['gvanrossum', 'rhettinger', 'mark.dickinson', 'vstinner', 'taleinat', 'ned.deily', 'Arfrever', 'steven.daprano', 'r.david.murray', 'python-dev', 'martin.panter', 'serhiy.storchaka', 'yselivanov', 'josh.r', 'llllllllll', 'levkivskyi', 'abarry', 'Stephan Hoyer']
pr_nums = []
priority = 'normal'
resolution = 'rejected'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue24379'
versions = ['Python 3.7']Metadata
Metadata
Assignees
Labels
3.7 (EOL)end of lifeend of lifeextension-modulesC modules in the Modules dirC modules in the Modules dirtype-featureA feature request or enhancementA feature request or enhancement
Activity
llllllllll commentedon Jun 4, 2015
I often find that when working with pandas and numpy I want to store slice objects in variables to pass around and re-use; however, the syntax for constructing a slice literal outside of an indexer is very different from the syntax used inside of a subscript. This patch proposes the following change:
This would be a singleton instance of a class that looks like:
The basic idea is to provide an alternative constructor to 'slice' that uses the subscript syntax. This allows people to write more understandable code.
Consider the following examples:
Again, this is not intended to make the code shorter, instead, it is designed to make it more clear what the slice object your are constructing looks like.
Another feature of the new
literalobject is that it is not limited to just the creation ofsliceinstances; instead, it is designed to mix slices and other types together. For example:These examples show that sometimes the subscript notation is much more clear that the non-subscript notation.
I believe that while this is trivial, it is very convinient to have on the slice type itself so that it is quickly available. This also prevents everyone from rolling their own version that is accesible in different ways (think Py_RETURN_NONE).
Another reason that chose this aproach is that it requires no change to the syntax to support.
There is a second change proposed here and that is to 'slice.__repr__'. This change makes the repr of a slice object match the new literal syntax to make it easier to read.
This change actually affects old behaviour so I am going to upload it as a seperate patch. I understand that the change to repr much be less desirable than the addition of 'slice.literal'
llllllllll commentedon Jun 4, 2015
Here is the patch that includes the updates to 'slice.__repr__'
rhettinger commentedon Jun 4, 2015
FWIW, I like this idea.
serhiy-storchaka commentedon Jun 4, 2015
Why not index the slice type itself? slice[1:2]
This looks as disadvantage.
stevendaprano commentedon Jun 4, 2015
I'm with Serhiy, I don't think we need a "literal", just make slice itself indexable:
The only question in my mind is what slice should do when given just a single index:
slice[0]
I suppose that should be a ValueError?
mdickinson commentedon Jun 4, 2015
For prior art, it's worth taking a look at NumPy, and in particular its
s_andindex_expfunctions:mdickinson commentedon Jun 4, 2015
(Correction: they're not functions, or even callables.)
llllllllll commentedon Jun 4, 2015
I originally considered this and I personally really like this syntax, but I was concerned with ambiguity with the typing module
I think some of the power of this concept comes from the fact that I can express a complicated indexer without worrying about how it desugars. I would personally prefer being able to have this return tuples and scalars so that the syntax is easier to explain.
taleinat commentedon Jun 9, 2015
(This should probably be discussed on the Python Ideas mailing list...)
I definitely like the idea of being able to construct slices etc. using "[]" syntax. I think this should be considered even if it is decided not to change the repr() of slices.
An important note here is that this is about more than slices:
Indeed, Joe's suggested slice.literal supports all of this, but we can't just modify slice to handle all of these cases.
What I'm missing is a way to use such an object to actually index/slice something. The only way I can currently think of is using a.__getitem__(), but that's quite ugly IMO.
llllllllll commentedon Jun 9, 2015
Sorry, I am not sure I understand what you mean by this? You can pass a slice object, or a tuple of slices in subscript notation.
Also, I am not currently subscribed to python-ideas; what is the common practice for posting new threads?
taleinat commentedon Jun 9, 2015
(see https://mail.python.org/mailman/listinfo/python-ideas)
But for x = [1,2,3,4], how will x[y] work for all of the following values of y?
NumPy's s_ "magic object" is a factory, returning objects of different types depending on the given input. If you want an actual slice.literal class, then you'll have to supply a way to convert it into an object usable for indexing/slicing, e.g.:
llllllllll commentedon Jun 10, 2015
The way this object works right now does not create instances of some inner class of slice, instead, indexing it returns the key without modification.
taleinat commentedon Jun 10, 2015
So, is this in any ways different than NumPy's s_?
47 remaining items
ilevkivskyi commentedon Nov 13, 2016
Serhiy, thank you for review! Here is a corrected patch.
serhiy-storchaka commentedon Nov 13, 2016
operator_subscript_norefleak_v2.patch LGTM. Waiting for Ned's decision about 3.6.
ned-deily commentedon Nov 13, 2016
I don't think this is appropriate for 3.6 now. We're a little more than 4 weeks from the final release - way past the feature code cut-off - and, from the comments here, there is no longer a total consensus that this feature should go back in at all after being pulled and largely forgotten about for a year.
ilevkivskyi commentedon Nov 13, 2016
Maybe then it makes sense to apply this to 3.7? It looks like most people are in favour of this (also on python-ideas), only Raymond is not sure/mildly against.
gvanrossum commentedon Nov 13, 2016
Actually I'm with Raymond -- I'm also not sure or mildly against (-0).
Given how easy it is to do without and how cumbersome using the operator
module is I don't see a great benefit. (IMO the operator module should be
the measure of *last* resort -- it is not to become part of anybody's
toolkit for common operators. But I seem to be a minority opinion here.)
taleinat commentedon Jun 14, 2018
So 3.8 then, or should this be closed?
FWIW I'm -1. IMO this should be a code recipe somewhere, no need for it to be in the stdlib.
gvanrossum commentedon Jun 16, 2018
Let's close it. Just because someone spent a lot of effort on a patch we don't have to accept it.
shoyer commentedon Jul 19, 2018
Raymond, Tal and Guido -- do any of you work routinely with multi-dimensional arrays?
In my experience as someone who uses Python everyday for numerical computing (and has been doing so for many years), the need for an operator like this comes up with some regularity. With multi-dimensional indexing, this allows lets you cut down quite a bit on boilerplate, e.g., compare
subscript[:, 0, ::-1] vs (slice(None), 0, slice(None, None, -1))
It's absolutely true that subscript is an easy four line recipe, and indeed a form of this recipe is already included in both NumPy and pandas. But I think this is a case where the lack of a common idiom is actively harmful. I do multi-dimensional indexing in using at least four different libraries (pandas, xarray, numpy and tensorflow), and it feels wrong to use a utility from numpy/pandas for other projects. I could write my own version of operator.subscript in each project (and yes, I've done so before), but for any individual use case it's less hassle to write things out the long way.
In practice, the preferred way to write such long expressions seems to be to redundantly repeat indexing operations, e.g.,
x[:, 0, ::-1]
y[:, 0, ::-1]
rather than
This is definitely non-ideal from a readability perspective. It's no longer immediately clear that these arrays are being indexed in the same way, and any changes would need to be applied twice.
vstinner commentedon Jul 20, 2018
Hi Stephan Hoyer,
IMHO a *closed* issue is not the most appropriate place to request Guido to change his mind. You may get more traction on python-ideas where you may find more supporters who need the operator.
The question is not only if the operator makes sense (obviously, it does, for you), but if it "belongs" to the standard library. Is it popular enough? Is it consistent with other functions of the operator module? etc.