[英]How to reorder list in Python to avoid repeating elements?
我试图检查列表中是否有任何连续的重复元素,然后对其重新排序,以免重复。 如果那是不可能的,则返回False。 例如:
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
您可以尝试概率方程式
重复次数最多的数字必须始终小于其他数字的计数。
[1,2,2,1,1,3,3,3,3,3,3,3]
7< (3+2) false
[1,2,2,1,1,3,3,3,3,3,3]
6< (3+2) true
[1,2,2,1,1,3,3,3,3,3]
5< (3+3) true
码
from itertools import groupby
>>> a =[1,2,2,1,1,3,3,3,3,3]
>>> s = [len(list(group)) for key, group in groupby(a)]
>>> s
[1, 2, 2, 5]
>>> max(s) < (sum(s)-max(s))
True
这是我使用非常有用的collections.Counter
类在实现的注释中提到的算法:
from collections import Counter
def check_repeat(sequence):
if not sequence:
return []
element_counts = Counter(sequence)
new_sequence = []
elements_chosen = 0
elements_needed = len(sequence)
previous_element_chosen = None
while elements_chosen < elements_needed:
candidates_needed = 1 if previous_element_chosen is None else 2
candidates = element_counts.most_common(candidates_needed)
candidate = (candidates[0] if
(len(candidates) < 2 or candidates[0][0] != previous_element_chosen)
else candidates[1])
if candidate[1] <= 0:
return False
else:
new_sequence.append(candidate[0])
element_counts[candidate[0]] -= 1
previous_element_chosen = candidate[0]
elements_chosen += 1
return new_sequence
如果“ None
是序列中的有效值,或者您在任何程度上都关心稳定性,则需要进行一些改进。 如果序列中的元素不可散列,那么它将根本无法工作。
三元candidate = ...
分配可能更清晰一些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.