This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Easy conversion between range and slice
Type: enhancement Stage:
Components: Versions: Python 3.10
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: nemeskeyd, rhettinger, serhiy.storchaka, steven.daprano
Priority: normal Keywords:

Created on 2021-01-18 10:31 by nemeskeyd, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg385184 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2021-01-18 10:31
It would be nice if there was an easy way to convert a range to a slice and vice versa. At least superficially the two are almost the same(*), yet if one wants to convert a slice to a range, he has to go through hoops to avoid potential errors, ending up with code such as:

s = slice(1, 10, 2)
r = range(s.start or 0, s.stop, s.step or 1)

It would be much nicer if the range and slice functions had a signature that accepts the other, which would simplify the above to just r(s).

(*) I don't know the implementation details, but is it even important to have to different objects for effectively the same concept? Cannot these two just be merged?
msg385185 - (view) Author: Dávid Nemeskey (nemeskeyd) Date: 2021-01-18 10:32
s/to different/two different/
msg385188 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-01-18 10:55
All versions older than 3.10 are in feature freeze and cannot get new features or enhancements, only bugfixes.

Slices are far more general than range objects. How do you propose to deal with slice objects such as this?

    slice('item', (23, {'key': 'value'}, 4.5), ('a', 2))

Even for plain integer arguments, the meanings are not the same. Consider the slice:

    slice(10, -2)  # Start at the 10th item, end at the second-last.

versus the range:

    range(10, -2)  # Empty range.
msg385189 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-01-18 11:06
> s.start or 0

Why 0? start=None is not the same as start=0 in slice. For example:

>>> 'abcdefgh'[slice(None, 3, -1)]
>>> 'abcdefgh'[slice(0, 3, -1)]

Slices and range objects are very different in many ways. It depends on your application how do you convert a slice to a range object, and in general case it does not make sense. Just use the way that is appropriate in your application.
msg385220 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-01-18 19:21
Perhaps the indices() method will suffice:

    >>> slice(None, 10, 2).indices(8)
    (0, 8, 2)

    >>> range(8)[:10:2]
    range(0, 8, 2)
Date User Action Args
2022-04-11 14:59:40adminsetgithub: 87122
2021-01-18 19:21:18rhettingersetnosy: + rhettinger
messages: + msg385220
2021-01-18 11:06:10serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg385189
2021-01-18 10:55:25steven.dapranosetnosy: + steven.daprano

messages: + msg385188
versions: - Python 3.6, Python 3.7, Python 3.8, Python 3.9
2021-01-18 10:32:10nemeskeydsetmessages: + msg385185
2021-01-18 10:31:17nemeskeydcreate