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;
}







32















I can check for a next() method, but is that enough? Is there an ideomatic way?










share|improve this question































    32















    I can check for a next() method, but is that enough? Is there an ideomatic way?










    share|improve this question



























      32












      32








      32


      7






      I can check for a next() method, but is that enough? Is there an ideomatic way?










      share|improve this question
















      I can check for a next() method, but is that enough? Is there an ideomatic way?







      python iterator






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      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
























          7 Answers
          7






          active

          oldest

          votes


















          50














          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.






          share|improve this answer





















          • 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



















          14














          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





          share|improve this answer





















          • 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



















          6














          To be an iterator an object must pass three tests:





          • obj has an __iter__ method


          • obj has a next method (or __next__ in Python 3)


          • obj.__iter__() returns obj


          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





          share|improve this answer
























          • 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











          • @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











          • @EthanFurman hmm? Wouldn't that mean you could just return true then?

            – PyRulez
            Jan 16 at 2:33



















          0














          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.





          share|improve this answer
























          • And this improves on the existing answers how?

            – jhpratt
            Jul 19 '18 at 2:08



















          0














          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






          share|improve this answer































            0














            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





            share|improve this answer

































              0














              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






              share|improve this answer
























                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
                });


                }
                });














                draft saved

                draft discarded


















                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









                50














                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.






                share|improve this answer





















                • 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
















                50














                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.






                share|improve this answer





















                • 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














                50












                50








                50







                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.






                share|improve this answer















                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                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














                • 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













                14














                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





                share|improve this answer





















                • 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
















                14














                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





                share|improve this answer





















                • 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














                14












                14








                14







                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





                share|improve this answer















                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






                share|improve this answer














                share|improve this answer



                share|improve this answer








                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














                • 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











                6














                To be an iterator an object must pass three tests:





                • obj has an __iter__ method


                • obj has a next method (or __next__ in Python 3)


                • obj.__iter__() returns obj


                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





                share|improve this answer
























                • 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











                • @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











                • @EthanFurman hmm? Wouldn't that mean you could just return true then?

                  – PyRulez
                  Jan 16 at 2:33
















                6














                To be an iterator an object must pass three tests:





                • obj has an __iter__ method


                • obj has a next method (or __next__ in Python 3)


                • obj.__iter__() returns obj


                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





                share|improve this answer
























                • 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











                • @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











                • @EthanFurman hmm? Wouldn't that mean you could just return true then?

                  – PyRulez
                  Jan 16 at 2:33














                6












                6








                6







                To be an iterator an object must pass three tests:





                • obj has an __iter__ method


                • obj has a next method (or __next__ in Python 3)


                • obj.__iter__() returns obj


                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





                share|improve this answer













                To be an iterator an object must pass three tests:





                • obj has an __iter__ method


                • obj has a next method (or __next__ in Python 3)


                • obj.__iter__() returns obj


                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






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 26 '16 at 0:09









                Ethan FurmanEthan Furman

                37.1k1292158




                37.1k1292158













                • 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











                • @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











                • @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











                • @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











                • @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

















                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











                0














                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.





                share|improve this answer
























                • And this improves on the existing answers how?

                  – jhpratt
                  Jul 19 '18 at 2:08
















                0














                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.





                share|improve this answer
























                • And this improves on the existing answers how?

                  – jhpratt
                  Jul 19 '18 at 2:08














                0












                0








                0







                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.





                share|improve this answer













                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.






                share|improve this answer












                share|improve this answer



                share|improve this answer










                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



















                • 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











                0














                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






                share|improve this answer




























                  0














                  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






                  share|improve this answer


























                    0












                    0








                    0







                    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






                    share|improve this answer













                    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







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 22 '18 at 11:25









                    user2390183user2390183

                    729714




                    729714























                        0














                        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





                        share|improve this answer






























                          0














                          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





                          share|improve this answer




























                            0












                            0








                            0







                            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





                            share|improve this answer















                            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






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Dec 29 '18 at 8:28

























                            answered Dec 29 '18 at 8:20









                            Shital ShahShital Shah

                            26k511099




                            26k511099























                                0














                                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






                                share|improve this answer




























                                  0














                                  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






                                  share|improve this answer


























                                    0












                                    0








                                    0







                                    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






                                    share|improve this answer













                                    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







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Mar 30 at 8:10









                                    TengeryeTengerye

                                    354316




                                    354316






























                                        draft saved

                                        draft discarded




















































                                        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.




                                        draft saved


                                        draft discarded














                                        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





















































                                        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







                                        Popular posts from this blog

                                        Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                                        ComboBox Display Member on multiple fields

                                        Is it possible to collect Nectar points via Trainline?