如何在Python中对列表重新排序以避免重复元素?
我试图检查列表是否有任何连续的重复元素,然后对其重新排序以避免重复。如果这是不可能的,那么返回False。例如:如何在Python中对列表重新排序以避免重复元素?,python,list,duplicates,sequence,Python,List,Duplicates,Sequence,我试图检查列表是否有任何连续的重复元素,然后对其重新排序以避免重复。如果这是不可能的,那么返回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
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
从itertools导入groupby
def检查重复(lst,最大值=1000):
“”“返回一个没有重复元素的列表。默认情况下,将尝试最多1000次迭代,如果找不到这样的列表,则返回False”“”
def HASSREPEAT(lst):
“”“如果有任何重复,则返回true”“”
返回len([x[0]表示groupby中的x(lst)]) 而hasreat(lst)和numIter则可以尝试概率方程
重复次数最多的数字必须始终小于其他数字的计数
[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
[1,2,2,1,1,3,3,3,3,3,3]
7<(3+2)错误
[1,2,2,1,1,3,3,3,3,3,3]
6<(3+2)正确
[1,2,2,1,1,3,3,3,3,3]
5<(3+3)正确
代码
从itertools导入groupby
>>>a=[1,2,2,1,1,3,3,3,3]
>>>s=[len(列表(组))表示键,groupby(a)中的组]
>>>
[1, 2, 2, 5]
>>>最大值<(总和-最大值))
符合事实的
以下是我在使用非常有用的集合实现的注释中提到的算法。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
从集合导入计数器
def检查_重复(顺序):
如果没有顺序:
返回[]
元素计数=计数器(序列)
新的_序列=[]
所选元素=0
所需元素=len(序列)
上一个元素所选元素=无
当所选元素小于所需元素时:
如果选择的前一个元素不是其他元素,则候选元素\u needed=1 2
候选元素=元素计数。最常见(需要候选元素)
候选人=(候选人[0]如果
(len(候选者)<2或候选者[0][0]!=先前选择的元素)
其他候选人[1])
如果候选者[1]如果您有需要改进的工作代码,它可能非常适合。只需头脑风暴一个算法,但我可能会建立每个元素的计数,然后添加一个非上一个元素的实例,该元素的未使用计数最高。如果在任何时候,所有非先前元素都有0个可用计数,则返回false。它应该只需要对原始列表进行两次遍历,一次计算元素,然后一次选择重新排序的列表中的每个元素。@Heslacher-从“是否有更优雅的解决方案”中,我假设OP有某种工作解决方案,并希望尽可能使其更优雅。@TigerhawkT3,摘自标题“如何在Python中对列表进行重新排序以避免重复元素?”这篇文章将以主题外的形式结束。但你是对的。我没有读这个问题,我的错。
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