Reputation:
I'm trying to move elements in a list such that the first two elements will always be appended to the last in reverse order until the list is the same one I started with. For example for
l = [1,2,3,4,5]
I should get
[1,2,3,4,5]
[3,4,5,2,1]
[5,2,1,4,3]
[1,4,3,2,5]
[3,2,5,4,1]
[5,4,1,2,3]
[1,2,3,4,5]
so six iterations will do.
Currently I have the following code
l = [1,2,3,4,5]
for i, j in zip(l, l[1:]):
l.append(l.pop(l.index(j)))
l.append(l.pop(l.index(i)))
What I was trying to do was to loop two consecutive elements and pop them and append to them as last two in the list in reversed order. This doesn't seem to work since printing the list at each step returns
[1, 2, 3, 4, 5]
[3, 4, 5, 2, 1]
[4, 5, 1, 3, 2]
[5, 1, 2, 4, 3]
so only the first iteration seems to work. What should I modify here?
Upvotes: 0
Views: 230
Reputation: 517
An easy way to do it with append()
and pop()
:
ls = [1, 2, 3, 4, 5]
newls = ls[2:] + [ls[1], ls[0]]
while newls != ls:
newls.append(newls.pop(1))
newls.append(newls.pop(0))
print(newls)
Upvotes: 0
Reputation: 27588
Here's a direct way to compute the steps needed for n distinct values:
(n-1) * (n+1) // 4 if n % 2 else n
Demo comparing an actually-do-it solution with my formula solution:
def naive_count(n):
initial = list(range(n))
a = initial.copy()
steps = 0
while True:
a = a[2:] + a[1::-1]
steps += 1
if a == initial:
return steps
def compute_count(n):
return (n-1) * (n+1) // 4 if n % 2 else n
for n in range(2, 14):
print(f'{n=}:', naive_count(n), compute_count(n))
Output:
n=2: 2 2
n=3: 2 2
n=4: 4 4
n=5: 6 6
n=6: 6 6
n=7: 12 12
n=8: 8 8
n=9: 20 20
n=10: 10 10
n=11: 30 30
n=12: 12 12
n=13: 42 42
And some larger ones:
for n in range(100, 110):
print(f'{n=}:', naive_count(n), compute_count(n))
n=100: 100 100
n=101: 2550 2550
n=102: 102 102
n=103: 2652 2652
n=104: 104 104
n=105: 2756 2756
n=106: 106 106
n=107: 2862 2862
n=108: 108 108
n=109: 2970 2970
And a larger check:
print(all(naive_count(n) == compute_count(n)
for n in range(2, 400)))
True
But don't expect me to explain the formula for odd n :-P
Upvotes: 2
Reputation: 1148
l = [1, 2, 3, 4, 5]
c = l.copy()
while True:
l = l[2:] + [l[1], l[0]]
print(l)
if l == c:
break
Upvotes: 8