pairs from a list

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

    #1

    pairs from a list

    I want to generate sequential pairs from a list.
    Here is a way::

    from itertools import izip, islice
    for x12 in izip(islice(x,0 ,None,2),islice (x,1,None,2)):
    print x12

    (Of course the print statement is just illustrative.)
    What is the fastest way? (Ignore the import time.)

    Thanks,
    Alan Isaac
  • Paul Rubin

    #2
    Re: pairs from a list

    Alan Isaac <aisaac@america n.eduwrites:
    (Of course the print statement is just illustrative.)
    What is the fastest way? (Ignore the import time.)
    You have to try a bunch of different ways and time them. One
    idea (untested):

    def pairs(seq):
    while True:
    yield (seq.next(), seq.next())

    Comment

    • George Sakkis

      #3
      Re: pairs from a list

      On Jan 21, 10:20 pm, Alan Isaac <ais...@america n.eduwrote:
      I want to generate sequential pairs from a list.
      Here is a way::
      >
      from itertools import izip, islice
      for x12 in izip(islice(x,0 ,None,2),islice (x,1,None,2)):
      print x12
      >
      (Of course the print statement is just illustrative.)
      What is the fastest way? (Ignore the import time.)
      Look up the timeit module and test yourself the various alternatives;
      that's the most reliable way to tell for sure.

      George

      Comment

      • Paddy

        #4
        Re: pairs from a list

        On Jan 22, 3:20 am, Alan Isaac <ais...@america n.eduwrote:
        I want to generate sequential pairs from a list.
        <<snip>>
        What is the fastest way? (Ignore the import time.)
        1) How fast is the method you have?
        2) How much faster does it need to be for your application?
        3) Are their any other bottlenecks in your application?
        4) Is this the routine whose smallest % speed-up would give the
        largest overall speed up of your application?

        - Paddy.


        Comment

        • George Sakkis

          #5
          Re: pairs from a list

          On Jan 22, 12:15 am, Paddy <paddy3...@goog lemail.comwrote :
          On Jan 22, 3:20 am, Alan Isaac <ais...@america n.eduwrote:I want to generate sequential pairs from a list.
          <<snip>>
          What is the fastest way? (Ignore the import time.)
          >
          1) How fast is the method you have?
          2) How much faster does it need to be for your application?
          3) Are their any other bottlenecks in your application?
          4) Is this the routine whose smallest % speed-up would give the
          largest overall speed up of your application?
          I believe the "what is the fastest way" question for such small well-
          defined tasks is worth asking on its own, regardless of whether it
          makes a difference in the application (or even if there is no
          application to begin with). Just because cpu cycles are cheap these
          days is not a good reason to be sloppy. Moreover, often the fastest
          pure Python version happens to be among the most elegant and concise,
          unlike other languages where optimization usually implies obfuscation.

          George

          Comment

          • Arnaud Delobelle

            #6
            Re: pairs from a list

            On Jan 22, 3:20 am, Alan Isaac <ais...@america n.eduwrote:
            I want to generate sequential pairs from a list.
            Here is a way::
            >
                from itertools import izip, islice
                for x12 in izip(islice(x,0 ,None,2),islice (x,1,None,2)):
                    print x12
            >
            (Of course the print statement is just illustrative.)
            What is the fastest way? (Ignore the import time.)
            >
            Thanks,
            Alan Isaac
            Don't know the fastest, but here's a very concise way:

            from itertools import izip

            def ipairs(seq):
            it = iter(seq)
            return izip(it, it)
            >>list(pairs(xr ange(10)))
            [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
            >>list(pairs('h ello'))
            [('h', 'e'), ('l', 'l')]

            --
            Arnaud

            Comment

            • Alan Isaac

              #7
              Re: pairs from a list

              I suppose my question should have been,
              is there an obviously faster way?
              Anyway, of the four ways below, the
              first is substantially fastest. Is
              there an obvious reason why?

              Thanks,
              Alan Isaac

              PS My understanding is that the behavior
              of the last is implementation dependent
              and not guaranteed.

              def pairs1(x):
              for x12 in izip(islice(x,0 ,None,2),islice (x,1,None,2)):
              yield x12

              def pairs2(x):
              xiter = iter(x)
              while True:
              yield xiter.next(), xiter.next()

              def pairs3(x):
              for i in range( len(x)//2 ):
              yield x[2*i], x[2*i+1],

              def pairs4(x):
              xiter = iter(x)
              for x12 in izip(xiter,xite r):
              yield x12

              Comment

              • Arnaud Delobelle

                #8
                Re: pairs from a list

                On Jan 22, 1:19 pm, Alan Isaac <ais...@america n.eduwrote:
                [...]
                PS My understanding is that the behavior
                of the last is implementation dependent
                and not guaranteed.
                [...]
                def pairs4(x):
                    xiter = iter(x)
                    for x12 in izip(xiter,xite r):
                        yield x12
                According to the docs [1], izip is defined to be equivalent to:

                def izip(*iterables ):
                iterables = map(iter, iterables)
                while iterables:
                result = [it.next() for it in iterables]
                yield tuple(result)

                This guarantees that it.next() will be performed from left to right,
                so there is no risk that e.g. pairs4([1, 2, 3, 4]) returns [(2, 1),
                (4, 3)].

                Is there anything else that I am overlooking?

                [1] http://docs.python.org/lib/itertools-functions.html

                --
                Arnaud

                Comment

                • Arnaud Delobelle

                  #9
                  Re: pairs from a list

                  On Jan 22, 1:19 pm, Alan Isaac <ais...@america n.eduwrote:
                  I suppose my question should have been,
                  is there an obviously faster way?
                  Anyway, of the four ways below, the
                  first is substantially fastest.  Is
                  there an obvious reason why?
                  Can you post your results?

                  I get different ones (pairs1 and pairs2 rewritten slightly to avoid
                  unnecessary indirection).

                  ====== pairs.py ===========
                  from itertools import *

                  def pairs1(x):
                  return izip(islice(x,0 ,None,2),islice (x,1,None,2))

                  def pairs2(x):
                  xiter = iter(x)
                  while True:
                  yield xiter.next(), xiter.next()

                  def pairs3(x):
                  for i in range( len(x)//2 ):
                  yield x[2*i], x[2*i+1],

                  def pairs4(x):
                  xiter = iter(x)
                  return izip(xiter,xite r)

                  def compare():
                  import timeit
                  for i in '1234':
                  t = timeit.Timer('l ist(pairs.pairs %s(l))' % i,
                  'import pairs; l=range(1000)')
                  print 'pairs%s: %s' % (i, t.timeit(10000) )

                  if __name__ == '__main__':
                  compare()
                  =============== ======

                  marigold:python arno$ python pairs.py
                  pairs1: 0.789824962616
                  pairs2: 4.08462786674
                  pairs3: 2.90438890457
                  pairs4: 0.536775827408

                  pairs4 wins.

                  --
                  Arnaud

                  Comment

                  • Alan Isaac

                    #10
                    Re: pairs from a list

                    Arnaud Delobelle wrote:
                    According to the docs [1], izip is defined to be equivalent to:
                    >
                    def izip(*iterables ):
                    iterables = map(iter, iterables)
                    while iterables:
                    result = [it.next() for it in iterables]
                    yield tuple(result)
                    >
                    This guarantees that it.next() will be performed from left to right,
                    so there is no risk that e.g. pairs4([1, 2, 3, 4]) returns [(2, 1),
                    (4, 3)].
                    >
                    Is there anything else that I am overlooking?
                    >
                    [1] http://docs.python.org/lib/itertools-functions.html

                    <URL:http://bugs.python.org/issue1121416>

                    fwiw,
                    Alan Isaac

                    Comment

                    • Arnaud Delobelle

                      #11
                      Re: pairs from a list

                      On Jan 22, 4:10 pm, Alan Isaac <ais...@america n.eduwrote:
                      <URL:http://bugs.python.org/issue1121416>
                      >
                      fwiw,
                      Alan Isaac
                      Thanks. So I guess I shouldn't take the code snippet I quoted as a
                      specification of izip but rather as an illustration.

                      --
                      Arnaud

                      Comment

                      • Paddy

                        #12
                        Re: pairs from a list

                        On Jan 22, 5:34 am, George Sakkis <george.sak...@ gmail.comwrote:
                        On Jan 22, 12:15 am, Paddy <paddy3...@goog lemail.comwrote :
                        >
                        On Jan 22, 3:20 am, Alan Isaac <ais...@america n.eduwrote:I want to generate sequential pairs from a list.
                        <<snip>>
                        What is the fastest way? (Ignore the import time.)
                        >
                        1) How fast is the method you have?
                        2) How much faster does it need to be for your application?
                        3) Are their any other bottlenecks in your application?
                        4) Is this the routine whose smallest % speed-up would give the
                        largest overall speed up of your application?
                        >
                        I believe the "what is the fastest way" question for such small well-
                        defined tasks is worth asking on its own, regardless of whether it
                        makes a difference in the application (or even if there is no
                        application to begin with).
                        Hi George,
                        You need to 'get it right' first. Micro optimizations for speed
                        without thought of the wider context is a bad habit to form and a time
                        waster.
                        If the routine is all that needs to be delivered and it does not
                        perform at an acceptable speed then find out what is acceptable and
                        optimise towards that goal. My questions were set to get posters to
                        think more about the need for speed optimizations and where they
                        should be applied, (if at all).

                        A bit of forethought might justify leaving the routine alone, or
                        optimising for readability instead.

                        - Paddy.

                        Comment

                        • Arnaud Delobelle

                          #13
                          Re: pairs from a list

                          On Jan 22, 6:34 pm, Paddy <paddy3...@goog lemail.comwrote :
                          [...]
                          Hi George,
                          You need to 'get it right' first. Micro optimizations for speed
                          without thought of the wider context is a bad habit to form and a time
                          waster.
                          If the routine is all that needs to be delivered and it does not
                          perform at an acceptable speed then find out what is acceptable and
                          optimise towards that goal. My questions were set to get posters to
                          think more about the need for speed optimizations and where they
                          should be applied, (if at all).
                          >
                          A bit of forethought might justify leaving the routine alone, or
                          optimising for readability instead.
                          But it's fun!

                          Some-of-us-can't-help-it'ly yours
                          --
                          Arnaud

                          Comment

                          • Alan G Isaac

                            #14
                            Re: pairs from a list

                            Steven D'Aprano wrote:
                            In fact, "fastest" isn't even a meaningful attribute. Does it mean:
                            >
                            * the worst-case is fastest
                            * the best-case is fastest
                            * the average-case is fastest
                            * fastest on typical data
                            * all of the above

                            I confess that it did not occur to me that there
                            might be an interesting distinction among these
                            cases for the question of how to get sequential
                            pairs from a list. How would one draw these
                            distinctions in this case?

                            Thanks,
                            Alan Isaac

                            PS Just for context, the sequential pairs were
                            needed in a simulation, but my question was
                            primarily prompted by my surprise that the
                            approaches I looked at differed as much as they did.

                            Comment

                            • George Sakkis

                              #15
                              Re: pairs from a list

                              On Jan 23, 4:37 am, Steven D'Aprano
                              <ste...@REMOVE. THIS.cybersourc e.com.auwrote:
                              On Tue, 22 Jan 2008 23:33:00 -0800, George Sakkis wrote:
                              As I mentioned already, I consider the seeking of the most efficient
                              solution a legitimate question, regardless of whether a "dumb" solution
                              is fast enough for an application. Call it a "don't be sloppy" principle
                              if you wish.
                              >
                              Sure, by why do you limit "efficient" and "don't be sloppy" to mean
                              "write the fastest executing code you can, regardless of every other
                              trade-off"?
                              I explicitly didn't limit sloppiness to inefficiency and mentioned
                              it's a tradeoff:

                              "... all else being equal or at least comparable (elegance,
                              conciseness, readability, etc.). Of course it's a tradeoff;
                              spending a week to save a few milliseconds on average is usually a
                              waste for most applications, but being a lazy keyboard banger writing
                              the first thing that pops into mind is not that good either."
                              But... do you write list.__len__() instead of len(list) to save a few
                              nanoseconds?
                              No, of course not, it's not worth it, but that doesn't mean that being
                              curious about what's faster and using timeit to find out is totally
                              worthless.

                              Another example: avoiding attribute lookups within a loop. I rarely
                              write
                              bar = foo.bar
                              for i in big_list: bar(i)

                              but it's valuable to know that it can make a difference when I really
                              need it. Always writing the first thing that "just works" prevents one
                              from even considering that there might be faster (or more elegant,
                              more general, etc.) alternatives.

                              George

                              Comment

                              Working...