Is the iteration protocol used when indexing a range object?
Since the range object produces values on demand, does it mean that anytime a range is indexed, the iteration protocol is invoked up to that index?
What I mean is when:
>>> R = range(1,11)
>>> print(R[5])
6
Since R[5]
isn't stored in memory, is it calculated every time by creating a new iterator? If not, how is it possible to index a range object?
python python-3.x indexing python-internals
add a comment |
Since the range object produces values on demand, does it mean that anytime a range is indexed, the iteration protocol is invoked up to that index?
What I mean is when:
>>> R = range(1,11)
>>> print(R[5])
6
Since R[5]
isn't stored in memory, is it calculated every time by creating a new iterator? If not, how is it possible to index a range object?
python python-3.x indexing python-internals
add a comment |
Since the range object produces values on demand, does it mean that anytime a range is indexed, the iteration protocol is invoked up to that index?
What I mean is when:
>>> R = range(1,11)
>>> print(R[5])
6
Since R[5]
isn't stored in memory, is it calculated every time by creating a new iterator? If not, how is it possible to index a range object?
python python-3.x indexing python-internals
Since the range object produces values on demand, does it mean that anytime a range is indexed, the iteration protocol is invoked up to that index?
What I mean is when:
>>> R = range(1,11)
>>> print(R[5])
6
Since R[5]
isn't stored in memory, is it calculated every time by creating a new iterator? If not, how is it possible to index a range object?
python python-3.x indexing python-internals
python python-3.x indexing python-internals
edited Nov 22 '18 at 11:30
Alex Riley
81.7k26162166
81.7k26162166
asked Nov 21 '18 at 22:45
masiewpaomasiewpao
84110
84110
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
No iterator is created here, and no iteration occurs. The range
object is implemented such that Python computes the value of R[5]
on-demand in constant time.1
If the index i
is not negative, the computation boils down to:
i * step + start
So in the case of your code R[5]
, this would be 5*1 + 1
which is 6.
If the index i
is negative, the length of R
is added to i
first, and then the value is computed as before:
(i + len(R)) * step + start
Python-internals
When you write R[5]
, this Python syntax is eventually translated into a call to PyObject_GetItem
, which inspects the object R
to see how it should proceed to find the item at index 5.
PyObject_GetItem
first checks the tp_as_mapping
slot of the range
type. This is not null; it holds a reference to a struct called range_as_mapping
. PyObject_GetItem
then checks to see what is in the mp_subscript
field of this struct:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
As you can see in the snippet above, it finds the range_subscript
function occupying the mp_subscript
field.2
Now range_subscript
inspects the arguments it was passed (R
and 5
) to decide if a single index or a slice was requested. The integer 5
means that just a single index is needed and so the function delegates the computation of the value to compute_range_item
. This function performs the computation to return the integer 6 as outlined in the first part of this answer.
1 I have assumed you are using CPython: other Python implementations may implement the range
object differently.
2 If you were to call len(R)
, you can see the internal function in mp_length
that is called to compute the length of R
(cf. Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).
In addition to these C-level functions, it might be worth mentioning the Python-level__getitem__
and__len__
, as well as the sequence protocol.
– lvc
Nov 22 '18 at 11:43
add a comment |
Nope. It is not.
However range
supports both iteration protocol and indexing (through getitem)
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421479%2fis-the-iteration-protocol-used-when-indexing-a-range-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
No iterator is created here, and no iteration occurs. The range
object is implemented such that Python computes the value of R[5]
on-demand in constant time.1
If the index i
is not negative, the computation boils down to:
i * step + start
So in the case of your code R[5]
, this would be 5*1 + 1
which is 6.
If the index i
is negative, the length of R
is added to i
first, and then the value is computed as before:
(i + len(R)) * step + start
Python-internals
When you write R[5]
, this Python syntax is eventually translated into a call to PyObject_GetItem
, which inspects the object R
to see how it should proceed to find the item at index 5.
PyObject_GetItem
first checks the tp_as_mapping
slot of the range
type. This is not null; it holds a reference to a struct called range_as_mapping
. PyObject_GetItem
then checks to see what is in the mp_subscript
field of this struct:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
As you can see in the snippet above, it finds the range_subscript
function occupying the mp_subscript
field.2
Now range_subscript
inspects the arguments it was passed (R
and 5
) to decide if a single index or a slice was requested. The integer 5
means that just a single index is needed and so the function delegates the computation of the value to compute_range_item
. This function performs the computation to return the integer 6 as outlined in the first part of this answer.
1 I have assumed you are using CPython: other Python implementations may implement the range
object differently.
2 If you were to call len(R)
, you can see the internal function in mp_length
that is called to compute the length of R
(cf. Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).
In addition to these C-level functions, it might be worth mentioning the Python-level__getitem__
and__len__
, as well as the sequence protocol.
– lvc
Nov 22 '18 at 11:43
add a comment |
No iterator is created here, and no iteration occurs. The range
object is implemented such that Python computes the value of R[5]
on-demand in constant time.1
If the index i
is not negative, the computation boils down to:
i * step + start
So in the case of your code R[5]
, this would be 5*1 + 1
which is 6.
If the index i
is negative, the length of R
is added to i
first, and then the value is computed as before:
(i + len(R)) * step + start
Python-internals
When you write R[5]
, this Python syntax is eventually translated into a call to PyObject_GetItem
, which inspects the object R
to see how it should proceed to find the item at index 5.
PyObject_GetItem
first checks the tp_as_mapping
slot of the range
type. This is not null; it holds a reference to a struct called range_as_mapping
. PyObject_GetItem
then checks to see what is in the mp_subscript
field of this struct:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
As you can see in the snippet above, it finds the range_subscript
function occupying the mp_subscript
field.2
Now range_subscript
inspects the arguments it was passed (R
and 5
) to decide if a single index or a slice was requested. The integer 5
means that just a single index is needed and so the function delegates the computation of the value to compute_range_item
. This function performs the computation to return the integer 6 as outlined in the first part of this answer.
1 I have assumed you are using CPython: other Python implementations may implement the range
object differently.
2 If you were to call len(R)
, you can see the internal function in mp_length
that is called to compute the length of R
(cf. Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).
In addition to these C-level functions, it might be worth mentioning the Python-level__getitem__
and__len__
, as well as the sequence protocol.
– lvc
Nov 22 '18 at 11:43
add a comment |
No iterator is created here, and no iteration occurs. The range
object is implemented such that Python computes the value of R[5]
on-demand in constant time.1
If the index i
is not negative, the computation boils down to:
i * step + start
So in the case of your code R[5]
, this would be 5*1 + 1
which is 6.
If the index i
is negative, the length of R
is added to i
first, and then the value is computed as before:
(i + len(R)) * step + start
Python-internals
When you write R[5]
, this Python syntax is eventually translated into a call to PyObject_GetItem
, which inspects the object R
to see how it should proceed to find the item at index 5.
PyObject_GetItem
first checks the tp_as_mapping
slot of the range
type. This is not null; it holds a reference to a struct called range_as_mapping
. PyObject_GetItem
then checks to see what is in the mp_subscript
field of this struct:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
As you can see in the snippet above, it finds the range_subscript
function occupying the mp_subscript
field.2
Now range_subscript
inspects the arguments it was passed (R
and 5
) to decide if a single index or a slice was requested. The integer 5
means that just a single index is needed and so the function delegates the computation of the value to compute_range_item
. This function performs the computation to return the integer 6 as outlined in the first part of this answer.
1 I have assumed you are using CPython: other Python implementations may implement the range
object differently.
2 If you were to call len(R)
, you can see the internal function in mp_length
that is called to compute the length of R
(cf. Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).
No iterator is created here, and no iteration occurs. The range
object is implemented such that Python computes the value of R[5]
on-demand in constant time.1
If the index i
is not negative, the computation boils down to:
i * step + start
So in the case of your code R[5]
, this would be 5*1 + 1
which is 6.
If the index i
is negative, the length of R
is added to i
first, and then the value is computed as before:
(i + len(R)) * step + start
Python-internals
When you write R[5]
, this Python syntax is eventually translated into a call to PyObject_GetItem
, which inspects the object R
to see how it should proceed to find the item at index 5.
PyObject_GetItem
first checks the tp_as_mapping
slot of the range
type. This is not null; it holds a reference to a struct called range_as_mapping
. PyObject_GetItem
then checks to see what is in the mp_subscript
field of this struct:
static PyMappingMethods range_as_mapping = {
(lenfunc)range_length, /* mp_length */
(binaryfunc)range_subscript, /* mp_subscript */
(objobjargproc)0, /* mp_ass_subscript */
};
As you can see in the snippet above, it finds the range_subscript
function occupying the mp_subscript
field.2
Now range_subscript
inspects the arguments it was passed (R
and 5
) to decide if a single index or a slice was requested. The integer 5
means that just a single index is needed and so the function delegates the computation of the value to compute_range_item
. This function performs the computation to return the integer 6 as outlined in the first part of this answer.
1 I have assumed you are using CPython: other Python implementations may implement the range
object differently.
2 If you were to call len(R)
, you can see the internal function in mp_length
that is called to compute the length of R
(cf. Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?).
edited Nov 22 '18 at 11:36
answered Nov 22 '18 at 11:29
Alex RileyAlex Riley
81.7k26162166
81.7k26162166
In addition to these C-level functions, it might be worth mentioning the Python-level__getitem__
and__len__
, as well as the sequence protocol.
– lvc
Nov 22 '18 at 11:43
add a comment |
In addition to these C-level functions, it might be worth mentioning the Python-level__getitem__
and__len__
, as well as the sequence protocol.
– lvc
Nov 22 '18 at 11:43
In addition to these C-level functions, it might be worth mentioning the Python-level
__getitem__
and __len__
, as well as the sequence protocol.– lvc
Nov 22 '18 at 11:43
In addition to these C-level functions, it might be worth mentioning the Python-level
__getitem__
and __len__
, as well as the sequence protocol.– lvc
Nov 22 '18 at 11:43
add a comment |
Nope. It is not.
However range
supports both iteration protocol and indexing (through getitem)
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
add a comment |
Nope. It is not.
However range
supports both iteration protocol and indexing (through getitem)
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
add a comment |
Nope. It is not.
However range
supports both iteration protocol and indexing (through getitem)
Nope. It is not.
However range
supports both iteration protocol and indexing (through getitem)
answered Nov 22 '18 at 2:01
ealfieealfie
1
1
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
add a comment |
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
1
1
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
Hi thanks for the response! I had a look at the docs for getitem but I am not sure I understand it. If it equates to using self[key] for an object, isn't there still the problem of knowing the value in a virtual sequence (since it's not stored in memory)?
– masiewpao
Nov 22 '18 at 9:50
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421479%2fis-the-iteration-protocol-used-when-indexing-a-range-object%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown