How can I check if an object is an iterator in Python?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I can check for a next()
method, but is that enough? Is there an ideomatic way?
python iterator
add a comment |
I can check for a next()
method, but is that enough? Is there an ideomatic way?
python iterator
add a comment |
I can check for a next()
method, but is that enough? Is there an ideomatic way?
python iterator
I can check for a next()
method, but is that enough? Is there an ideomatic way?
python iterator
python iterator
edited Mar 26 '16 at 0:10
Ethan Furman
37.1k1292158
37.1k1292158
asked Jun 11 '10 at 14:16
Juanjo ContiJuanjo Conti
10.8k3094122
10.8k3094122
add a comment |
add a comment |
7 Answers
7
active
oldest
votes
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
but that's not as fast and concise as the new approach.
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
add a comment |
An object is iterable if it implements the iterator protocol.
You could check the presence of __iter__()
method with:
hasattr(object,'__iter__')
in Python 2.x this approach misses str objects and other built-in sequence types like unicode, xrange, buffer. It works in Python 3.
Another way is to test it with iter method :
try:
iter(object)
except TypeError:
#not iterable
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
add a comment |
To be an iterator an object must pass three tests:
obj
has an__iter__
method
obj
has anext
method (or__next__
in Python 3)
obj.__iter__()
returnsobj
So, a roll-your-own test would look like:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
Would callingobj.__iter__()
run the risk of changing something?
– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? Ifobj
is an iterator, then yes, it shouldn't change something. But ifobj
is not an iterator,obj.__iter__()
is allowed to have side effects.
– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if theobj
in question is not, in fact, an iterator then my answer to him doesn't apply.
– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
|
show 2 more comments
answer from python sourcecode doc comments:
{python install path}/Versions/3.5/lib/python3.5/types.py
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "__next__" attributes instead.
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
add a comment |
As the question is about Iterator not Iterable and considering usage of iterator, a simplest and pythonic way of doing this
iterable = [1,2]
iterator = iter(iterable)
def isIterator(obj):
try:
next(obj, None)
return True
except TypeError:
return False
>>> isIterator(iterable)
False
>>> isIterator(iterator)
True
Yes. Checking on next() should be enough
add a comment |
There is a better method than other answers have suggested.
In Python we have two kinds of things: Iterable
and Iterator
. An object is Iterable
if it can give you Iterator
. It does so when you use iter()
on it. An object is Iterator
if you can use next()
to sequentially browse through its elements. For example, map()
returns Iterator
and list
is Iterable
.
Here are more details.
Below code illustrates how to check for these types:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
add a comment |
This example comes from the book Effective Python and is illustrated in this post.
An iterable produces an iterator. Any iterator is also an iterable,
but produces itself as the iterator:
>>> list_iter = iter()
>>> iter(list_iter) is list_iter
True
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%2f3023503%2fhow-can-i-check-if-an-object-is-an-iterator-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
but that's not as fast and concise as the new approach.
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
add a comment |
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
but that's not as fast and concise as the new approach.
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
add a comment |
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
but that's not as fast and concise as the new approach.
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
In Python 2.6 or better, the designed-in idiom for such behavioral checks is a "membership check" with the abstract base class in the collections
module of the standard library:
>>> import collections
>>> isinstance('ciao', collections.Iterable)
True
>>> isinstance(23, collections.Iterable)
False
>>> isinstance(xrange(23), collections.Iterable)
True
Indeed, this kind of checks is the prime design reason for the new abstract base classes (a second important one is to provide "mixin functionality" in some cases, which is why they're ABCs rather than just interfaces -- but that doesn't apply to collections.Iterable
, it exists strictly to allow such checks with isinstance
or issubclass
). ABCs allow classes that don't actually inherit from them to be "registered" as subclasses anyway, so that such classes can be "subclasses" of the ABC for such checks; and, they can internally perform all needed checks for special methods (__iter__
in this case), so you don't have to.
If you're stuck with older releases of Python, "it's better to ask forgiveness than permission":
def isiterable(x):
try: iter(x)
except TypeError: return False
else: return True
but that's not as fast and concise as the new approach.
Note that for this special case you'll often want to special-case strings (which are iterable but most application contexts want to treat as "scalars" anyway). Whatever approach you're using to check iterableness, if you need such special casing just prepend a check for isinstance(x, basestring)
-- for example:
def reallyiterable(x):
return not isinstance(x, basestring) and isinstance(x, collections.Iterable)
Edit: as pointed out in a comment, the question focuses on whether an object is an iter***ator*** rather than whether it's iter***able*** (all iterators are iterable, but not vice versa -- not all iterables are iterators). isinstance(x, collections.Iterator)
is the perfectly analogous way to check for that condition specifically.
edited Jun 11 '10 at 18:07
answered Jun 11 '10 at 15:11
Alex MartelliAlex Martelli
635k12910461284
635k12910461284
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
add a comment |
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
13
13
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
The questions asks if an object is an iterator, not if it is iterable. So you should use collections.Iterator instead of collections.Iterable
– Dave Kirby
Jun 11 '10 at 17:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
@Dave, right, let me edit to clarify.
– Alex Martelli
Jun 11 '10 at 18:04
add a comment |
An object is iterable if it implements the iterator protocol.
You could check the presence of __iter__()
method with:
hasattr(object,'__iter__')
in Python 2.x this approach misses str objects and other built-in sequence types like unicode, xrange, buffer. It works in Python 3.
Another way is to test it with iter method :
try:
iter(object)
except TypeError:
#not iterable
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
add a comment |
An object is iterable if it implements the iterator protocol.
You could check the presence of __iter__()
method with:
hasattr(object,'__iter__')
in Python 2.x this approach misses str objects and other built-in sequence types like unicode, xrange, buffer. It works in Python 3.
Another way is to test it with iter method :
try:
iter(object)
except TypeError:
#not iterable
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
add a comment |
An object is iterable if it implements the iterator protocol.
You could check the presence of __iter__()
method with:
hasattr(object,'__iter__')
in Python 2.x this approach misses str objects and other built-in sequence types like unicode, xrange, buffer. It works in Python 3.
Another way is to test it with iter method :
try:
iter(object)
except TypeError:
#not iterable
An object is iterable if it implements the iterator protocol.
You could check the presence of __iter__()
method with:
hasattr(object,'__iter__')
in Python 2.x this approach misses str objects and other built-in sequence types like unicode, xrange, buffer. It works in Python 3.
Another way is to test it with iter method :
try:
iter(object)
except TypeError:
#not iterable
edited Jun 11 '10 at 14:33
answered Jun 11 '10 at 14:19
systempuntooutsystempuntoout
43.3k37148230
43.3k37148230
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
add a comment |
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
1
1
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
Creating iterator could be expensive whereas checking attribute existence is always fast.
– Piotr Dobrogost
Sep 29 '12 at 16:35
1
1
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
this checks if the object is iterable, not it if is an iterator
– c z
Aug 29 '18 at 12:43
add a comment |
To be an iterator an object must pass three tests:
obj
has an__iter__
method
obj
has anext
method (or__next__
in Python 3)
obj.__iter__()
returnsobj
So, a roll-your-own test would look like:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
Would callingobj.__iter__()
run the risk of changing something?
– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? Ifobj
is an iterator, then yes, it shouldn't change something. But ifobj
is not an iterator,obj.__iter__()
is allowed to have side effects.
– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if theobj
in question is not, in fact, an iterator then my answer to him doesn't apply.
– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
|
show 2 more comments
To be an iterator an object must pass three tests:
obj
has an__iter__
method
obj
has anext
method (or__next__
in Python 3)
obj.__iter__()
returnsobj
So, a roll-your-own test would look like:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
Would callingobj.__iter__()
run the risk of changing something?
– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? Ifobj
is an iterator, then yes, it shouldn't change something. But ifobj
is not an iterator,obj.__iter__()
is allowed to have side effects.
– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if theobj
in question is not, in fact, an iterator then my answer to him doesn't apply.
– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
|
show 2 more comments
To be an iterator an object must pass three tests:
obj
has an__iter__
method
obj
has anext
method (or__next__
in Python 3)
obj.__iter__()
returnsobj
So, a roll-your-own test would look like:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
To be an iterator an object must pass three tests:
obj
has an__iter__
method
obj
has anext
method (or__next__
in Python 3)
obj.__iter__()
returnsobj
So, a roll-your-own test would look like:
def is_iterator(obj):
if (
hasattr(obj, '__iter__') and
hasattr(obj, 'next') and # or __next__ in Python 3
callable(obj.__iter__) and
obj.__iter__() is obj
):
return True
else:
return False
answered Mar 26 '16 at 0:09
Ethan FurmanEthan Furman
37.1k1292158
37.1k1292158
Would callingobj.__iter__()
run the risk of changing something?
– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? Ifobj
is an iterator, then yes, it shouldn't change something. But ifobj
is not an iterator,obj.__iter__()
is allowed to have side effects.
– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if theobj
in question is not, in fact, an iterator then my answer to him doesn't apply.
– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
|
show 2 more comments
Would callingobj.__iter__()
run the risk of changing something?
– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? Ifobj
is an iterator, then yes, it shouldn't change something. But ifobj
is not an iterator,obj.__iter__()
is allowed to have side effects.
– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if theobj
in question is not, in fact, an iterator then my answer to him doesn't apply.
– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
Would calling
obj.__iter__()
run the risk of changing something?– Bob Stein
Sep 25 '17 at 18:38
Would calling
obj.__iter__()
run the risk of changing something?– Bob Stein
Sep 25 '17 at 18:38
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@BobStein-VisiBone: Only if the object is buggy.
– Ethan Furman
Feb 6 '18 at 16:49
@EthanFurman What do you mean? If
obj
is an iterator, then yes, it shouldn't change something. But if obj
is not an iterator, obj.__iter__()
is allowed to have side effects.– PyRulez
Jan 16 at 0:09
@EthanFurman What do you mean? If
obj
is an iterator, then yes, it shouldn't change something. But if obj
is not an iterator, obj.__iter__()
is allowed to have side effects.– PyRulez
Jan 16 at 0:09
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if the
obj
in question is not, in fact, an iterator then my answer to him doesn't apply.– Ethan Furman
Jan 16 at 2:32
@PyRulez: Presumably BobStein's question was about iterators, and my answer was definitely about iterators; if the
obj
in question is not, in fact, an iterator then my answer to him doesn't apply.– Ethan Furman
Jan 16 at 2:32
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
@EthanFurman hmm? Wouldn't that mean you could just return true then?
– PyRulez
Jan 16 at 2:33
|
show 2 more comments
answer from python sourcecode doc comments:
{python install path}/Versions/3.5/lib/python3.5/types.py
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "__next__" attributes instead.
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
add a comment |
answer from python sourcecode doc comments:
{python install path}/Versions/3.5/lib/python3.5/types.py
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "__next__" attributes instead.
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
add a comment |
answer from python sourcecode doc comments:
{python install path}/Versions/3.5/lib/python3.5/types.py
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "__next__" attributes instead.
answer from python sourcecode doc comments:
{python install path}/Versions/3.5/lib/python3.5/types.py
# Iterators in Python aren't a matter of type but of protocol. A large
# and changing number of builtin types implement *some* flavor of
# iterator. Don't check the type! Use hasattr to check for both
# "__iter__" and "__next__" attributes instead.
answered Jul 19 '18 at 2:05
yoyoyoyo
7915
7915
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
add a comment |
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
And this improves on the existing answers how?
– jhpratt
Jul 19 '18 at 2:08
add a comment |
As the question is about Iterator not Iterable and considering usage of iterator, a simplest and pythonic way of doing this
iterable = [1,2]
iterator = iter(iterable)
def isIterator(obj):
try:
next(obj, None)
return True
except TypeError:
return False
>>> isIterator(iterable)
False
>>> isIterator(iterator)
True
Yes. Checking on next() should be enough
add a comment |
As the question is about Iterator not Iterable and considering usage of iterator, a simplest and pythonic way of doing this
iterable = [1,2]
iterator = iter(iterable)
def isIterator(obj):
try:
next(obj, None)
return True
except TypeError:
return False
>>> isIterator(iterable)
False
>>> isIterator(iterator)
True
Yes. Checking on next() should be enough
add a comment |
As the question is about Iterator not Iterable and considering usage of iterator, a simplest and pythonic way of doing this
iterable = [1,2]
iterator = iter(iterable)
def isIterator(obj):
try:
next(obj, None)
return True
except TypeError:
return False
>>> isIterator(iterable)
False
>>> isIterator(iterator)
True
Yes. Checking on next() should be enough
As the question is about Iterator not Iterable and considering usage of iterator, a simplest and pythonic way of doing this
iterable = [1,2]
iterator = iter(iterable)
def isIterator(obj):
try:
next(obj, None)
return True
except TypeError:
return False
>>> isIterator(iterable)
False
>>> isIterator(iterator)
True
Yes. Checking on next() should be enough
answered Nov 22 '18 at 11:25
user2390183user2390183
729714
729714
add a comment |
add a comment |
There is a better method than other answers have suggested.
In Python we have two kinds of things: Iterable
and Iterator
. An object is Iterable
if it can give you Iterator
. It does so when you use iter()
on it. An object is Iterator
if you can use next()
to sequentially browse through its elements. For example, map()
returns Iterator
and list
is Iterable
.
Here are more details.
Below code illustrates how to check for these types:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
add a comment |
There is a better method than other answers have suggested.
In Python we have two kinds of things: Iterable
and Iterator
. An object is Iterable
if it can give you Iterator
. It does so when you use iter()
on it. An object is Iterator
if you can use next()
to sequentially browse through its elements. For example, map()
returns Iterator
and list
is Iterable
.
Here are more details.
Below code illustrates how to check for these types:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
add a comment |
There is a better method than other answers have suggested.
In Python we have two kinds of things: Iterable
and Iterator
. An object is Iterable
if it can give you Iterator
. It does so when you use iter()
on it. An object is Iterator
if you can use next()
to sequentially browse through its elements. For example, map()
returns Iterator
and list
is Iterable
.
Here are more details.
Below code illustrates how to check for these types:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
There is a better method than other answers have suggested.
In Python we have two kinds of things: Iterable
and Iterator
. An object is Iterable
if it can give you Iterator
. It does so when you use iter()
on it. An object is Iterator
if you can use next()
to sequentially browse through its elements. For example, map()
returns Iterator
and list
is Iterable
.
Here are more details.
Below code illustrates how to check for these types:
from collections.abc import Iterable, Iterator
r = [1, 2, 3]
e = map(lambda x:x, r)
print(isinstance(r, Iterator)) # False, because can't apply next
print(isinstance(e, Iterator)) # True
print(isinstance(r, Iterable)) # True, because can apply iter()
print(isinstance(e, Iterable)) # True, note iter() returns self
edited Dec 29 '18 at 8:28
answered Dec 29 '18 at 8:20
Shital ShahShital Shah
26k511099
26k511099
add a comment |
add a comment |
This example comes from the book Effective Python and is illustrated in this post.
An iterable produces an iterator. Any iterator is also an iterable,
but produces itself as the iterator:
>>> list_iter = iter()
>>> iter(list_iter) is list_iter
True
add a comment |
This example comes from the book Effective Python and is illustrated in this post.
An iterable produces an iterator. Any iterator is also an iterable,
but produces itself as the iterator:
>>> list_iter = iter()
>>> iter(list_iter) is list_iter
True
add a comment |
This example comes from the book Effective Python and is illustrated in this post.
An iterable produces an iterator. Any iterator is also an iterable,
but produces itself as the iterator:
>>> list_iter = iter()
>>> iter(list_iter) is list_iter
True
This example comes from the book Effective Python and is illustrated in this post.
An iterable produces an iterator. Any iterator is also an iterable,
but produces itself as the iterator:
>>> list_iter = iter()
>>> iter(list_iter) is list_iter
True
answered Mar 30 at 8:10
TengeryeTengerye
354316
354316
add a comment |
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%2f3023503%2fhow-can-i-check-if-an-object-is-an-iterator-in-python%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