Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #94896

Re: Most pythonic way of rotating a circular list to a canonical point

Newsgroups comp.lang.python
Date 2015-08-02 03:51 -0700
References <e71d031f-f1cf-4e16-9b5a-963d02373fb5@googlegroups.com>
Message-ID <7c6c6764-2b84-4c94-8a79-ed0408f00021@googlegroups.com> (permalink)
Subject Re: Most pythonic way of rotating a circular list to a canonical point
From pavlovevidence@gmail.com

Show all headers | View raw


On Saturday, August 1, 2015 at 1:34:44 PM UTC-7, Lukas Barth wrote:
> Hi!
> 
> I have a list of numbers that I treat as "circular", i.e. [1,2,3] and [2,3,1] should be the same. Now I want to rotate these to a well defined status, so that I can can compare them.
> 
> If all elements are unique, the solution is easy: find the minimum element, find its index, then use mylist[:index] + mylist[index:], i.e. the minimum element will always be at the beginning.
> 
> But say I have [0,1,0,2,0,3]. I can in fact guarantee that no *pair* will appear twice in that list, i.e. I could search for the minimum, if that is unique go on as above, otherwise find *all* positions of the minimum, see which is followed by the smallest element, and then rotate that position to the front.
> 
> Now that seems an awful lot of code for a (seemingly?) simple problem. Is there a nice, pythonic way to do this?
> 
> Thanks for enlightening me!

[[[Warning: all code untested, sorry!]]]

The general problem (no assumptions about the items in the list except that they're all sortable together) is interesting.  It doesn't seem like a simple one to me at all.  An acceptable criterion would be if you took the lexically smallest value of every rotation of the list; that would yield the same result for every initial rotation.  You can do it in like this:

    anchor = min(range(len(X)),key=lambda i:X[i:]+X[:i])
    canonical_X = X[anchor:]+X[:anchor]

I doubt this would be that efficient, though, since it happens to construct every single rotation in the process of scanning.  However, you'll notice that the minimum lexical value can only occur when the starting point is the minimum value in the list, so you can almost certainly improve performace to find all the minimum values and only test those rotations, especially if the number of minima is small compared to the list size.  (However, be sure to timeit for actual evidence rather than my guessing.)

    min_value = min(X)
    i = X.index(min_value)
    while True:
        start_points.append(i)
        try:
            i = X.index(min_value,i+1)
        except ValueError:
            break
    anchor = min(start_points,key=lambda i:X[i:]+X[:i])
    canonical_X = X[anchor:]+X[:anchor]



Your lists aren't arbitrary, however and they actually seem to be ordered pairs (in which case the first question I have is why not have it be a list of 2-tuples? but I can imagine a few reasons).  You say the pairs are known to be unique, so all you have to do is find the index of the minimum pair.  One can use zip and slicing to generate 2-tuples from the flat list, whence you can find the minimum.

    pairs = list(zip(X[0::2],X[1::2]))
    min_pair = min(pairs)
    anchor = 2 * pairs.index(min_pair)
    canonical_X = X[anchor:]+X[:anchor]


Carl Banks

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 13:34 -0700
  Re: Most pythonic way of rotating a circular list to a canonical point Emile van Sebille <emile@fenx.com> - 2015-08-01 13:49 -0700
    Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 14:12 -0700
      Re: Most pythonic way of rotating a circular list to a canonical point Emile van Sebille <emile@fenx.com> - 2015-08-01 14:29 -0700
  Re: Most pythonic way of rotating a circular list to a canonical point Marko Rauhamaa <marko@pacujo.net> - 2015-08-01 23:57 +0300
    Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 14:04 -0700
      Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 16:32 -0700
      Re: Most pythonic way of rotating a circular list to a canonical point Marko Rauhamaa <marko@pacujo.net> - 2015-08-02 09:25 +0300
  Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 14:24 -0700
    Re: Most pythonic way of rotating a circular list to a canonical point Emile van Sebille <emile@fenx.com> - 2015-08-01 14:36 -0700
      Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 15:51 -0700
        Re: Most pythonic way of rotating a circular list to a canonical point Joel Goldstick <joel.goldstick@gmail.com> - 2015-08-01 18:58 -0400
        Re: Most pythonic way of rotating a circular list to a canonical point Josh English <Joshua.R.English@gmail.com> - 2015-08-01 16:43 -0700
        Re: Most pythonic way of rotating a circular list to a canonical point Steven D'Aprano <steve@pearwood.info> - 2015-08-02 18:17 +1000
    Re: Most pythonic way of rotating a circular list to a canonical point Paul Rubin <no.email@nospam.invalid> - 2015-08-01 14:43 -0700
      Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 15:53 -0700
        Re: Most pythonic way of rotating a circular list to a canonical point Paul Rubin <no.email@nospam.invalid> - 2015-08-01 19:47 -0700
          Re: Most pythonic way of rotating a circular list to a canonical point Paul Rubin <no.email@nospam.invalid> - 2015-08-01 20:02 -0700
    Re: Most pythonic way of rotating a circular list to a canonical point Cameron Simpson <cs@zip.com.au> - 2015-08-02 08:25 +1000
      Re: Most pythonic way of rotating a circular list to a canonical point Lukas Barth <mail@tinloaf.de> - 2015-08-01 15:55 -0700
        Re: Most pythonic way of rotating a circular list to a canonical point Cameron Simpson <cs@zip.com.au> - 2015-08-02 11:20 +1000
  Re: Most pythonic way of rotating a circular list to a canonical point wolfram.hinderer@googlemail.com - 2015-08-01 17:07 -0700
  Re: Most pythonic way of rotating a circular list to a canonical point pavlovevidence@gmail.com - 2015-08-02 03:51 -0700
  Re: Most pythonic way of rotating a circular list to a canonical point Tim Chase <python.list@tim.thechases.com> - 2015-08-02 13:19 -0500
  Re: Most pythonic way of rotating a circular list to a canonical point Larry Hudson <orgnut@yahoo.com> - 2015-08-02 13:01 -0700
    Re: Most pythonic way of rotating a circular list to a canonical point Joonas Liik <liik.joonas@gmail.com> - 2015-08-02 23:58 +0300
      Re: Most pythonic way of rotating a circular list to a canonical point Larry Hudson <orgnut@yahoo.com> - 2015-08-03 12:56 -0700
    Re: Most pythonic way of rotating a circular list to a canonical point Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-08-03 15:19 +0100

csiph-web