简体   繁体   English

如何在列表中按特定顺序对特定项目进行排序

[英]How sort specific items in specific order in a list

Hello everybody I am trying to do an algorithm that sort specific items in a specifig order.大家好,我正在尝试一种算法,以特定顺序对特定项目进行排序。 Let's assume that we have a list of items : [1, 2, 1, 3, 3, 3, 2, 2, 2, 2, 2, 1, 3, 2, 2, 1] there is three different type of items here : 1, 2 and 3. I want to sort this list in order to have a sequence of items that follows the same types.假设我们有一个项目列表: [1, 2, 1, 3, 3, 3, 2, 2, 2, 2, 2, 1, 3, 2, 2, 1] 共有三种不同类型的项目此处:1、2 和 3。我想对这个列表进行排序,以便得到一系列遵循相同类型的项目。 In the sorting process we can't move the position's items, we just can remove some items and the result should be the longest.在排序过程中我们不能移动位置的项目,我们只能删除一些项目,结果应该是最长的。 The result of this algorithm should be :这个算法的结果应该是:
[1, 1, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2] I don't know why my algorithm doesn't work : [1, 1, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2] 我不知道为什么我的算法不起作用:


# start list
givenList = [1, 2, 1, 3, 3, 3, 2, 2, 2, 2, 2, 1, 3, 2, 2,1]
# whish list (just for an example)
whish = [1, 1, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2]
# list grouped by items ( [ [1], [2], [1], [3, 3, 3], [2, 2, 2, 2, 2] ....])
sortedList = []

# we group the elements
lastElement=0
for currentElement in givenList :
  if currentElement != lastElement :
    sortedList.append([currentElement])
    lastElement=currentElement
  else : sortedList[-1].append(currentElement)

# we print the grouped items
for index, element in enumerate(sortedList) :
  print("Bloc : ", index , " contient : " , element)

# we sort the same elements by group
result=[]
for index, element in enumerate(sortedList) :
  # we pass if it's the first group because he has no backward element
  if(index == 0) : continue
  # we pass if it's the last group because he has no afterward element
  if(index == len(sortedList) - 1) : continue
  # backward group
  backwardList = sortedList[index - 1]
  # current group
  currentList = sortedList[index]
  # afterward group
  forwardList = sortedList[index + 1]
  # if the backward groupelement type is the same as the forward
  if backwardList[0] == forwardList[0] :
    # and if the backwardlist contains more element that the current group
    if(len(backwardList) >= len(currentList)) :
      # we add the concatenation of the backwards and the forwards group
      result.append(backwardList + forwardList)
  elif backwardList[0] != forwardList[0] :
    # else we just add the current group
    result.append(currentList)
    
# we degroup the grouped and sorted list
resultSorted=[]
for e in result:
  for i in e:
    resultSorted.append(i)

# 
print("#"*20)
print("Given : ", givenList)
print("Whish : ", whish)
print("Result : ", resultSorted)
print("#"*20)


You can try this implementation with itertools.groupby :您可以使用itertools.groupby尝试此实现:

from itertools import groupby

l = [1, 2, 1, 3, 3, 3, 2, 2, 2, 2, 2, 1, 3, 2, 2, 1]

def get_max(elems, current_elems=None):
    if current_elems is None:
        current_elems = []

    for idx, (color, count) in enumerate(elems):
        if color in [c for c, _ in current_elems[:-1]]:
            continue
        yield current_elems + [(color, count)]
        yield from get_max( elems[idx+1:], current_elems + [(color, count)] )

elems = [(v, sum(1 for _ in g)) for v, g in groupby(l)]
l, _ = max(((v, sum(c for _, c in v)) for v in get_max(elems)), key=lambda k: k[1], default=[[], None])

out = []
for v, g in groupby(l, key=lambda k: k[0]):
    for _, c in g:
        out.extend([v] * c)

print(out)

Prints:印刷:

[1, 1, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2]

Other test cases:其他测试用例:

l = [1, 2, 3]       # [1, 2, 3]
l = [1, 2, 3, 1, 1] # [2, 3, 1, 1]

The best solution is :最好的解决办法是:

def solve(l):
    def aux(i, current, exclude):
        if i==len(l):
            return []
        val = l[i]
        if val in exclude:
            return aux(i+1, current, exclude)
        elif val == current:
            return [val] + aux(i+1, current, exclude)
        else:
            exclude.add(current)
            s1 = [val] + aux(i+1, val, exclude)
            exclude.remove(current)
            s2 = aux(i+1, current, exclude)
            if len(s1)>len(s2):
                return s1
            return s2

    return aux(0, -1, set())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM