Iteration over two sequences

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

    Iteration over two sequences

    I am just starting to learn Python, mostly by going through the examples
    in Dive Into Python and by playing around.

    Quite frequently, I find the need to iterate over two sequences at the
    same time, and I have a bit of a hard time finding a way to do this in a
    "pythonic" fashion. One example is a dot product. The straight-ahead
    C-like way of doing it would be:

    def dotproduct(a, b):
    psum = 0
    for i in range(len(a)):
    psum += a[i]*b[i]
    return psum

    However, the range(len(a)) term is awfully un-pythonic :)
    The built-in function map() gives me a way of "transposin g" the a list
    and the b list, and now I can handle it with a list comprehension:

    def dotproduct(a, b):
    return sum([x*y for x, y in map(None, a, b)])

    My concern is one of efficiency: it seems to me that I have two loops
    there: first one implied with map(...) and then the for loop -- which
    seems like a waste since I feel I should be able to do the
    multiplication via an argument to map. So far I have come up with an
    alternative via defining a separate function:

    def dotproduct(a, b):
    def prod(x,y): return x*y
    return sum(map(prod, a, b))

    I suppose I could also use a lambda here -- but is there a different,
    efficient, and obvious solution that I'm overlooking?


    Thanks,
    Henrik

    --
    "On some great and glorious day the plain folks of the land will reach
    in their heart's desire at last and the White House will be adorned by
    a downright moron."
    -H.L. Mencken (1880-1956) American Writer
  • Diez B. Roggisch

    #2
    Re: Iteration over two sequences

    zip or izip is your friend:

    import itertools

    a = [1,2,3]
    b = ['a', 'b', 'c']

    for a,b in itertools.izip( a, b):
    print a, b

    --
    Regards,

    Diez B. Roggisch

    Comment

    • Paul McGuire

      #3
      Re: Iteration over two sequences

      "Henrik Holm" <news+0409@henr ikholm.com> wrote in message
      news:1gq9qs9.3s nutr1s4mcn2N%ne ws+0409@henrikh olm.com...[color=blue]
      > I am just starting to learn Python, mostly by going through the examples
      > in Dive Into Python and by playing around.
      >
      > Quite frequently, I find the need to iterate over two sequences at the
      > same time, and I have a bit of a hard time finding a way to do this in a
      > "pythonic" fashion. One example is a dot product. The straight-ahead
      > C-like way of doing it would be:
      >
      > def dotproduct(a, b):
      > psum = 0
      > for i in range(len(a)):
      > psum += a[i]*b[i]
      > return psum
      >
      > However, the range(len(a)) term is awfully un-pythonic :)
      > The built-in function map() gives me a way of "transposin g" the a list
      > and the b list, and now I can handle it with a list comprehension:
      >
      > def dotproduct(a, b):
      > return sum([x*y for x, y in map(None, a, b)])
      >
      > My concern is one of efficiency: it seems to me that I have two loops
      > there: first one implied with map(...) and then the for loop -- which
      > seems like a waste since I feel I should be able to do the
      > multiplication via an argument to map. So far I have come up with an
      > alternative via defining a separate function:
      >
      > def dotproduct(a, b):
      > def prod(x,y): return x*y
      > return sum(map(prod, a, b))
      >
      > I suppose I could also use a lambda here -- but is there a different,
      > efficient, and obvious solution that I'm overlooking?
      >
      >
      > Thanks,
      > Henrik
      >
      > --
      > "On some great and glorious day the plain folks of the land will reach
      > in their heart's desire at last and the White House will be adorned by
      > a downright moron."
      > -H.L. Mencken (1880-1956) American Writer[/color]

      zip maybe?

      def dotproduct(a,b) :
      return sum([x*y for x,y in zip(a,b)])

      -- Paul


      Comment

      • Richard Brodie

        #4
        Re: Iteration over two sequences


        "Henrik Holm" <news+0409@henr ikholm.com> wrote in message
        news:1gq9qs9.3s nutr1s4mcn2N%ne ws+0409@henrikh olm.com...
        [color=blue]
        > I suppose I could also use a lambda here -- but is there a different,
        > efficient, and obvious solution that I'm overlooking?[/color]

        Check the itertools recipes in the library documentation.


        Comment

        • Henrik Holm

          #5
          Re: Iteration over two sequences

          Richard Brodie <R.Brodie@rl.ac .uk> wrote:
          [color=blue]
          > "Henrik Holm" <news+0409@henr ikholm.com> wrote in message
          > news:1gq9qs9.3s nutr1s4mcn2N%ne ws+0409@henrikh olm.com...
          >[color=green]
          > > I suppose I could also use a lambda here -- but is there a different,
          > > efficient, and obvious solution that I'm overlooking?[/color]
          >
          > Check the itertools recipes in the library documentation.[/color]

          Thanks,

          the itertools seem to contain several useful functions.

          --
          "On some great and glorious day the plain folks of the land will reach
          in their heart's desire at last and the White House will be adorned by
          a downright moron."
          -H.L. Mencken (1880-1956) American Writer

          Comment

          • John Lenton

            #6
            Re: Iteration over two sequences

            > Quite frequently, I find the need to iterate over two sequences at
            the[color=blue]
            > same time, and I have a bit of a hard time finding a way to do this[/color]
            in a[color=blue]
            > "pythonic" fashion. One example is a dot product. The straight-ahead
            > C-like way of doing it would be:
            >
            > def dotproduct(a, b):
            > psum = 0
            > for i in range(len(a)):
            > psum += a[i]*b[i]
            > return psum[/color]

            for this particular example, the most pythonic way is to do nothing at
            all, or, if you must call it dotproduct,[color=blue][color=green][color=darkred]
            >>> from Numeric import dot as dotproduct[/color][/color][/color]

            Comment

            • It's me

              #7
              Re: Iteration over two sequences

              I tried this and I got:

              [(1, 'a'), (2, 'b'), (3, 'c')]

              But if I change:

              a=[1,2]

              I got:

              [(1, 'c')]

              Why is that? I thought I should be getting:

              [(1, 'a'),(2,'b')]

              ?????


              "Diez B. Roggisch" <deetsNOSPAM@we b.de> wrote in message
              news:34kvs0F4bq iviU1@individua l.net...[color=blue]
              > zip or izip is your friend:
              >
              > import itertools
              >
              > a = [1,2,3]
              > b = ['a', 'b', 'c']
              >
              > for a,b in itertools.izip( a, b):
              > print a, b
              >
              > --
              > Regards,
              >
              > Diez B. Roggisch[/color]


              Comment

              • Henrik Holm

                #8
                Re: Iteration over two sequences

                John Lenton <jlenton@gmail. com> wrote:
                [color=blue][color=green]
                > > def dotproduct(a, b):
                > > psum = 0
                > > for i in range(len(a)):
                > > psum += a[i]*b[i]
                > > return psum[/color]
                >
                > for this particular example, the most pythonic way is to do nothing at
                > all, or, if you must call it dotproduct,[color=green][color=darkred]
                > >>> from Numeric import dot as dotproduct[/color][/color][/color]

                Downloading, installing, and getting to know numerical modules for
                Python is mext on my list :). However, I was under the impression that
                Numarray is preferred to Numeric -- is that correct? Are these two
                competing packages? (Hopefully this is not flame war bait...)

                --
                "On some great and glorious day the plain folks of the land will reach
                in their heart's desire at last and the White House will be adorned by
                a downright moron."
                -H.L. Mencken (1880-1956) American Writer

                Comment

                • Steven Bethard

                  #9
                  Re: Iteration over two sequences

                  Henrik Holm wrote:[color=blue]
                  > John Lenton <jlenton@gmail. com> wrote:
                  >
                  >[color=green][color=darkred]
                  >>>def dotproduct(a, b):
                  >>> psum = 0
                  >>> for i in range(len(a)):
                  >>> psum += a[i]*b[i]
                  >>> return psum[/color]
                  >>
                  >>for this particular example, the most pythonic way is to do nothing at
                  >>all, or, if you must call it dotproduct,
                  >>[color=darkred]
                  >>>>>from Numeric import dot as dotproduct[/color][/color]
                  >
                  >
                  > Downloading, installing, and getting to know numerical modules for
                  > Python is mext on my list :). However, I was under the impression that
                  > Numarray is preferred to Numeric -- is that correct? Are these two
                  > competing packages? (Hopefully this is not flame war bait...)
                  >[/color]

                  Numarray is the replacement for Numeric. Some people are still using
                  Numeric for a variety of reasons, e.g. they use a package that has not
                  been updated to use numarray, they can't afford the performance penalty
                  that numarray has for small arrays, etc.

                  Steve

                  Comment

                  • John Lenton

                    #10
                    Re: Iteration over two sequences

                    > Downloading, installing, and getting to know numerical modules for[color=blue]
                    > Python is mext on my list :). However, I was under the impression[/color]
                    that[color=blue]
                    > Numarray is preferred to Numeric -- is that correct? Are these two
                    > competing packages? (Hopefully this is not flame war bait...)[/color]

                    Numeric's dot uses, if the appropriate libraries are installed,
                    processor-tuned code (it tries to load blas, and an attempt to load
                    blas will load atlas if present). Last time I checked numarray did not,
                    and so Numeric's dot is (or was) faster than numarray's dot by an order
                    of magnitude (and more, as the size of the array grew).

                    Comment

                    • Scott David Daniels

                      #11
                      Re: Iteration over two sequences

                      Henrik Holm wrote:[color=blue]
                      > John Lenton <jlenton@gmail. com> wrote:
                      >
                      >[color=green][color=darkred]
                      >>>def dotproduct(a, b):
                      >>> psum = 0
                      >>> for i in range(len(a)):
                      >>> psum += a[i]*b[i]
                      >>> return psum[/color]
                      >>
                      >>for this particular example, the most pythonic way is to do nothing at
                      >>all, or, if you must call it dotproduct,
                      >>[color=darkred]
                      >>>>>from Numeric import dot as dotproduct[/color][/color]
                      >
                      >
                      > Downloading, installing, and getting to know numerical modules for
                      > Python is mext on my list :). However, I was under the impression that
                      > Numarray is preferred to Numeric -- is that correct? Are these two
                      > competing packages? (Hopefully this is not flame war bait...)
                      >[/color]
                      Numarray is the future, Numeric is the "past", but in the present
                      Numeric is better (and more mature) at some stuff than Numarray.

                      Learning both is not much harder than learning one, actually (they
                      share a lot).

                      --Scott David Daniels
                      Scott.Daniels@A cm.Org

                      Comment

                      • Terry Reedy

                        #12
                        Re: Iteration over two sequences


                        "It's me" <itsme@yahoo.co m> wrote in message
                        news:MrdFd.1064 6$5R.6473@newss vr21.news.prodi gy.com...[color=blue]
                        >I tried this and I got:
                        > [(1, 'a'), (2, 'b'), (3, 'c')]
                        > But if I change:
                        > a=[1,2]
                        > I got:
                        > [(1, 'c')]
                        > Why is that? I thought I should be getting:
                        > [(1, 'a'),(2,'b')]
                        > ?????[/color]

                        Cut and paste the actual input and output for an interactive session with a
                        freshly started interpreter and perhaps we can answer for sure.

                        Terry J. Reedy




                        Comment

                        • Diez B. Roggisch

                          #13
                          Re: Iteration over two sequences

                          My example is somewhat flawed because it assigns a and b the values of the
                          iteration - so in the end, b is 'c', and only setting a to [1,2] will show
                          your results.

                          Use c and d for the variables in the for-statments, and things work as
                          expected.
                          --
                          Regards,

                          Diez B. Roggisch

                          Comment

                          • David Isaac

                            #14
                            Re: Iteration over two sequences


                            "Scott David Daniels" <Scott.Daniels@ Acm.Org> wrote in message
                            news:41e58244$1 @nntp0.pdx.net:[color=blue]
                            > Numarray is the future, Numeric is the "past",[/color]

                            This statement is not obviously true.
                            See the recent discussion on the developer lists.
                            (Search for Numeric3.)
                            Alan Isaac


                            Comment

                            • Scott David Daniels

                              #15
                              Re: Iteration over two sequences

                              David Isaac wrote:[color=blue]
                              > "Scott David Daniels" <Scott.Daniels@ Acm.Org> wrote in message
                              > news:41e58244$1 @nntp0.pdx.net:
                              >[color=green]
                              >>Numarray is the future, Numeric is the "past",[/color]
                              >
                              > This statement is not obviously true. See the recent discussion on the
                              > developer lists. (Search for Numeric3.)
                              > Alan Isaac[/color]

                              I stand corrected. Sorry to have conveyed a mis-impression that I have
                              held for a while. It was my understanding that the Numeric code was so
                              hard to maintain that our fearless leader would never let it in the
                              codebase. Hence, Numarray was born. A quick look through some of the
                              Numeric3 messages leaves me with the impression that Numeric3 will be
                              more of a rebirth than a small change. I have used Numeric for several
                              big projects (that died for commercial, rather than technical, reasons),
                              and have certainly appreciated it. The thrust of my comment holds,
                              however, "learning both is not much harder than learning one."

                              --Scott David Daniels
                              Scott.Daniels@A cm.Org

                              Comment

                              Working...