我试图检查一个列表是否有任何连续的重复元素,然后重新排序,以避免重复。如果那是不可能的,那么返回False。例如:如何在Python中重新排列列表以避免重复元素?
checkRepeat([1,2])
Out[61]: [1, 2]
checkRepeat([1,2,2])
Out[62]: [2, 1, 2]
checkRepeat([1,2,2,1,1])
Out[63]: [1, 2, 1, 2, 1]
checkRepeat([1,2,2,1,1,3,3,3,3])
Out[64]: [1, 3, 1, 3, 2, 1, 3, 2, 3]
checkRepeat([1,2,2,1,1,3,3,3,3,3])
Out[65]: [3, 1, 3, 2, 3, 1, 3, 1, 3, 2]
checkRepeat([1,2,2,1,1,3,3,3,3,3,3])
Out[66]: [3, 1, 3, 1, 3, 1, 3, 2, 3, 2, 3]
checkRepeat([1,2,2,1,1,3,3,3,3,3,3,3])
Out[67]: False
这是我的。有没有更优雅的解决方案?
from itertools import groupby
def checkRepeat(lst,maxIter=1000):
"""Returns a list that has no repeating elements. Will try for a max of 1000 iterations by default and return False if such a list can't be found"""
def hasRepeat(lst):
"""Returns true if there are any repeats"""
return len([x[0] for x in groupby(lst)]) < len(lst)
offset=numIter=0
while hasRepeat(lst) and numIter<maxIter:
for i,curElt in enumerate(lst):
try:
if lst[i]==lst[i+1]:
lst[i+1],lst[(i+offset) % len(lst)] = lst[(i+offset) % len(lst)],lst[i+1] #swap j+1 with j+offset. wrap around the list
except:
break
offset+=1
numIter+=1
if numIter==maxIter:
return False
else:
return lst
如果您有需要改进的工作代码,它可能非常适合[代码评论](http://codereview.stackexchange.com/)。 – TigerhawkT3
只是头脑风暴的算法,但我可能会通过建立每个元素的计数,然后添加具有最高未使用计数的非上一个元素的实例。如果在任何时候您的所有非先前元素都有0个可用计数,则返回false。它只需要对原始列表进行两次遍历,一次对元素进行计数,然后一次对重新排序的列表中的每个元素进行选择。 –
@Heslacher - 从“是否有更优雅的解决方案”,我认为OP有某种工作解决方案,并希望尽可能使其更优雅。 – TigerhawkT3