container-indepentent iteration code ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • flacco

    #1

    container-indepentent iteration code ?


    is there a way to iterate over the *values* in a list/dict/whatever,
    regardless of whether it's a list, dict, or whatever? ie, the iteration
    code will not know beforehand what kind of container it's getting.


  • Jeremy Bowers

    #2
    Re: container-indepentent iteration code ?

    On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
    [color=blue]
    >
    > is there a way to iterate over the *values* in a list/dict/whatever,
    > regardless of whether it's a list, dict, or whatever? ie, the iteration
    > code will not know beforehand what kind of container it's getting.[/color]

    In what way does

    for obj in container:

    not meet your needs?

    Comment

    • flacco

      #3
      Re: container-indepentent iteration code ?

      Jeremy Bowers wrote:[color=blue]
      > On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
      >[color=green]
      >>is there a way to iterate over the *values* in a list/dict/whatever,
      >>regardless of whether it's a list, dict, or whatever? ie, the iteration
      >>code will not know beforehand what kind of container it's getting.[/color]
      >
      > In what way does
      >
      > for obj in container:
      >
      > not meet your needs?[/color]

      i always want obj to be the value. dicts, for example, yield keys
      instead of values (i think?)...


      Comment

      • Jeremy Bowers

        #4
        Re: container-indepentent iteration code ?

        On Wed, 08 Sep 2004 20:35:56 -0400, flacco wrote:[color=blue]
        > i always want obj to be the value. dicts, for example, yield keys
        > instead of values (i think?)...[/color]

        Ah, that clarifies it for me. "Values" is a bit of an overloaded term. :-)

        The problem you're running into here is that the "standard iterator" kind
        of "defines" the "values" the container has. That's the only idea of
        "default set of values in a container" that Python is going to understand.

        Thus, since the fundamental issue is a disagreement between you and Python
        about what constitutes a "value" out of a dict (and as the human in this
        transaction you are the right one :-) ), I don't see any way to avoid
        explaining your idea to Python. You can make it convenient:

        def values(iterable ):
        if isinstance(iter able, dict):
        return iterable.iterva lues()
        # Whatever other special cases you may need
        return iter(iterable)

        for obj in values(containe r):
        # etc.

        but there's no switch or anything that will do what you want. Sorry.
        You're always going to have to explain what you mean by "whatever" to
        Python.

        Stepping up one meta-level, another possibility that you may consider is
        creating some container classes that match whatever your heterogenous
        containment needs are, then you can make *those* containers work naturally
        without the function I showed above. Without knowing more about your
        problem, I can't know if that is better in general.

        Consider this:

        class IterateGivesMeV alues(dict):
        # It is quite likely your domain will give you a better
        # name :-)
        def __iter__(self):
        return self.itervalues ()

        igmv = IterateGivesMeV alues()
        igmv["key"] = "value"
        for i in igmv:
        print i

        will print "value" instead of "dict". If you build your structures out of
        such objects your life may, or may not, be easier.

        Comment

        • Raymond Hettinger

          #5
          Re: container-indepentent iteration code ?

          [flacco][color=blue]
          > is there a way to iterate over the *values* in a list/dict/whatever,
          > regardless of whether it's a list, dict, or whatever? ie, the iteration
          > code will not know beforehand what kind of container it's getting.[/color]

          try:
          it = obj.itervalues( )
          except AttributeError:
          it = iter(obj)
          for value in it:
          . . .


          Raymond Hettinger



          Comment

          • Terry Reedy

            #6
            Re: container-indepentent iteration code ?


            "flacco" <flacco002@spam badTwilight-systems.com> wrote in message
            news:10jv9ae988 bbnb7@corp.supe rnews.com...[color=blue]
            > Jeremy Bowers wrote:[color=green]
            >> On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
            >>[color=darkred]
            >>>is there a way to iterate over the *values* in a list/dict/whatever,
            >>>regardless of whether it's a list, dict, or whatever? ie, the iteration
            >>>code will not know beforehand what kind of container it's getting.[/color]
            >>
            >> In what way does
            >>
            >> for obj in container:
            >>
            >> not meet your needs?[/color]
            >
            > i always want obj to be the value. dicts, for example, yield keys
            > instead of values (i think?)...[/color]

            When iterators were introduced, there was discussion of whether

            for x in somedict:

            should iterate over dict.keys(), dict.values(), dict.items(), or continue
            to be illegal. dict.keys() won as being most useful because most commonly
            needed. Iterating over values or items continues to have to be explicit.

            Terry J. Reedy



            Comment

            • Alex Martelli

              #7
              Re: container-indepentent iteration code ?

              flacco <flacco002@spam badTwilight-systems.com> wrote:
              ...[color=blue][color=green]
              > > In what way does
              > >
              > > for obj in container:
              > >
              > > not meet your needs?[/color]
              >
              > i always want obj to be the value. dicts, for example, yield keys
              > instead of values (i think?)...[/color]

              Yep, as Jeremy explained, iter(container) [[implicitly called by the for
              statement]] lets the container decide which are the container's *items*.

              If you don't like the way a container defines what its items are for
              default iteration purposes you need to tweak things in the cases you
              don't like (another example might be files: their items are lines --
              what if you want characters, or blocks of 37 characters, or ...? no way
              Python can possibly guess without explicit action on your part!).


              Alex

              Comment

              • Jeff Epler

                #8
                Re: container-indepentent iteration code ?

                def viter(container ):
                """Iterate over values of a container"""
                if hasattr(contain er, "itervalues "):
                return container.iterv alues()
                return iter(container)

                Jeff

                -----BEGIN PGP SIGNATURE-----
                Version: GnuPG v1.2.1 (GNU/Linux)

                iD8DBQFBQF6cJd0 1MZaTXX0RAgt3AJ 9dHLhksoNnLnASj xYy6HWoQvzcQgCe Iupe
                ZH8D81nH8HYzqfh 1x4iPlP0=
                =oSx2
                -----END PGP SIGNATURE-----

                Comment

                Working...