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

2015-08-01 Thread Lukas Barth
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!

Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Saturday, August 1, 2015 at 10:57:19 PM UTC+2, Marko Rauhamaa wrote:
> 
> def circularly_equal(l1, l2):
> length = len(l1)
> if length != len(l2):
> return False
> twice = l1 + l1
> for i in range(length):
> if twice[i:i + length] == l2:
> return True
> return False
> 

Nice idea! But I actually really need those "canonic rotations", since I'm 
hashing them somewhere..

Lukas

-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Saturday, August 1, 2015 at 10:51:03 PM UTC+2, Emile van Sebille wrote:
> Is the problem to determine if one list of circular numbers 'matches' 
> another one despite rotation status?  If so, I'd do something like:

Well.. no. I actually really need this "canonical" rotation, since I'm hashing 
this, returning it to other parts of the software, etc..

But thanks!

Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
Perhaps I should clarify a bit:

- I definitely need a "canonical rotation" - just a comparison result is not 
enough

- It does not matter what that rotation is. Starting with the smallest element 
was just an idea by me, any rotation that can easily produced will do.
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Saturday, August 1, 2015 at 11:37:48 PM UTC+2, Emile van Sebille wrote:
> Well, it looks to me that I don't know what a 'canonical rotation' is -- 

That's because it is not defined. ;)

I need a way to rotate one of these lists in a way so that it will produce the 
same output every time, regardless of what the input rotation was.

Example:

[0,1,2,3,4] => [0,1,2,3,4]
[2,3,4,0,1] => [0,1,2,3,4]
[3,4,0,1,2] => [0,1,2,3,4]
...

It doesn't have to be "[0,1,2,3,4]", it can just as well be [2,3,4,1,0], as 
long as it's always the same.

Did that make it clearer?

Thanks a lot,

Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Saturday, August 1, 2015 at 11:43:28 PM UTC+2, Paul Rubin wrote:
> How large are these lists supposed to be? 

Potentially large. Not so large though that iterating them (multiple times) 
should be a problem.

> [Concatenated Hashes]
> 
> If the lists are very large that doesn't sound so great due to storage
> requirements..

Also, that still doesn't compute that one "canonical ordering"...

Thanks,

Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Sunday, August 2, 2015 at 12:32:25 AM UTC+2, Cameron Simpson wrote:
> Fine. This also eliminates any solution which just computes a hash.

Exactly.

> Might I suggest instead simply starting with the leftmost element in the 
> first 
> list; call this elem0.  Then walk the second list from 0 to len(list2). If 
> that 
> element equals elem0, _then_ compare the list at that point as you suggested.
>
> Is there an aspect of this which doesn't work?

The problem is: When I compute a hash over list1 (in its canonical form), I do 
not yet know list2 (or list3, or listN...) against which they will be compared 
later..
 
Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list


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

2015-08-01 Thread Lukas Barth
On Sunday, August 2, 2015 at 1:05:32 AM UTC+2, Oscar Benjamin wrote:
> Do you really need the canonical rotation or just a hash that is invariant 
> under rotations?

Having that canonical rotation would make the code simpler and faster, 
probably, but a rotationally invariant hash is a good start.

> I don't know of a solution to the former that is better than what you already 
> have but the latter is an easier problem: Find the minimum element. Compute 
> the hash of the rotated sequence for each occurrence of the least common 
> element. Add those hashes together or multiply them or some similar 
> operation. That's your hash that will compare equal for any rotation of a 
> given sequence.

Yes, that sounds like an idea if I decide to just go with the hash. Thanks!

Lukas
-- 
https://mail.python.org/mailman/listinfo/python-list