Basically I need to order a list, so that an element is not the same as the element that comes after or before it. I searched for a solution but couldn't find one so I wrote this function myself.
For example, [1,2,2,3,1,3,3] should come out as [3,1,2,3,1,2,3], [3,2,3,1,2,3,1] or [2,1,3,1,3,2,3] and so on.
def unorder(alist):
multi_lvl_list = []
unord_list = []
alist.sort()
# makes a new list that holds lists where same elements
# are grouped together
start = 0
for i in range(len(alist)):
if i == len(alist)-1:
if alist[i] != alist[i-1]:
multi_lvl_list.append([alist[i]])
else:
multi_lvl_list.append(alist[start:])
elif alist[i] != alist[i+1]:
multi_lvl_list.append(alist[start:i+1])
start = i+1
i += 1
multi_lvl_list.sort(key=len)
'''
goes over every list and pops out one element to a third list
if there are many same elements they will be put
to the end of the list
'''
while len(multi_lvl_list) > 0:
for idx, val in enumerate(multi_lvl_list):
unord_list.append(val.pop())
if len(val) == 0:
del multi_lvl_list[idx]
'''
go over the list in reverse. if x == x-1 try to put x in the
beginning of the list. becourse there are
more likely different elements
'''
for i in range(len(unord_list)-1, -1, -1):
if unord_list[i] == unord_list[i-1]:
for j in range(len(unord_list)):
if j == 0:
if unord_list[i] != unord_list[0]:
unord_list.insert(0, unord_list[i])
del unord_list[i+1]
elif unord_list[i] != unord_list[j] and unord_list[i] != unord_list[j+1]:
unord_list.insert(j+1, unord_list[i])
del unord_list[i+1]
else:
break
return unord_list
It seems to work in cases where it's possible to make such a list, but I'm pretty sure there is a more efficient way and the code can be optimized.
[1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
? \$\endgroup\$