How to reorder list in Python to avoid repeating elements? -


i trying check if list has consecutive repeating elements and then reorder such repeats avoided. if impossible, return false. example:

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 

here have. there more elegant solution?

from itertools import groupby def checkrepeat(lst,maxiter=1000):     """returns list has no repeating elements. try max of 1000 iterations default , return false if such list can't found"""      def hasrepeat(lst):         """returns true if there repeats"""         return len([x[0] x in groupby(lst)]) < len(lst)       offset=numiter=0             while hasrepeat(lst) , numiter<maxiter:         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 j+offset. wrap around list             except:                 break         offset+=1         numiter+=1     if numiter==maxiter:         return false     else:         return lst 

here's algorithm alluded in comments implemented, using useful collections.counter class:

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 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 

this needs refinement if none valid value in sequence, or if care stability degree. if elements of sequence not hashable, won't work @ all.

and ternary candidate = ... assignment clearer broken bit more.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -