简体   繁体   English

列表中的反向递增序列

[英]reverse ascending sequences in a list

Trying to figure out how to reverse multiple ascending sequences in a list. 试图弄清楚如何在列表中反转多个升序序列。

For instance: input = [1,2,2,3] to output = [2,1,3,2] . 例如: input = [1,2,2,3]output = [2,1,3,2]

I have used mylist.reverse() but of course it reverses to [3,2,2,1] . 我使用了mylist.reverse()但当然它反转为[3,2,2,1] Not sure which approach to take? 不确定采取哪种方法?

Example in detail: 详细示例:

So lets say [5, 7, 10, 2, 7, 8, 1, 3] is the input - the output should be [10,7,5,8,7,2,3,1] . 因此,可以说[5, 7, 10, 2, 7, 8, 1, 3]是输入-输出应为[10,7,5,8,7,2,3,1] In this example the first 3 elements 5,7,10 are in ascending order, 2,7,8 is likewise in ascending order and 1,3 also in ascending order. 在该示例中,前3个元素5,7,10按升序排列,2,7,8同样按升序排列,1,3也按升序排列。 The function should be able to recognize this pattern and reverse each sequence and return a new list. 该函数应该能够识别该模式并反转每个序列并返回一个新列表。

All you need is to find all non-descreasing subsequences and reverse them: 您所需要的只是找到所有非减少的子序列并将其反转:

In [47]: l = [5, 7, 10, 2, 7, 8, 1, 3]    

In [48]: res = []

In [49]: start_idx = 0

In [50]: for idx in range(max(len(l) - 1, 0)):
    ...:     if l[idx] >= l[idx - 1]:
    ...:         continue
    ...:     step = l[start_idx:idx]
    ...:     step.reverse()
    ...:     res.extend(step)
    ...:     start_idx = idx
    ...:

In [51]: step = l[start_idx:]

In [52]: step.reverse()

In [53]: res.extend(step)

In [54]: print(res)
[10, 7, 5, 8, 7, 2, 3, 1]

For increasing subsequences you need to change if l[idx] >= l[idx - 1] to if l[idx] > l[idx - 1] if l[idx] >= l[idx - 1]if l[idx] > l[idx - 1]if l[idx] > l[idx - 1]需要更改子序列

There is probably a more elegant way to do this, but one approach would be to use itertools.zip_longest along with enumerate to iterate over sequential element pairs in your list and keep track of each index where the sequence is no longer ascending or the list is exhausted in order to slice, reverse, and extend your output list with the sliced items. 有一种更优雅的方法可以做到这一点,但一种方法是使用itertools.zip_longestenumerate来迭代列表中的顺序元素对,并跟踪序列不再提升的每个索引或列表是耗尽,以便切片,反转和扩展您的输出列表与切片项目。

from itertools import zip_longest

d = [5, 7, 10, 2, 7, 8, 1, 3]

results = []
stop = None
for i, (a, b) in enumerate(zip_longest(d, d[1:])):
    if not b or b <= a:
        results.extend(d[i:stop:-1])
        stop = i

print(results)
# [10, 7, 5, 8, 7, 2, 3, 1]

Walk the list making a bigger and bigger window from x to y positions. 走在列表中,从x到y位置创建一个越来越大的窗口。 When you find a place where the next number is not ascending, or reach the end, reverse-slice the window you just covered and add it to the end of an output list: 当您找到下一个数字未提升或到达末尾的位置时,对刚刚覆盖的窗口进行反向切片并将其添加到输出列表的末尾:

data = [5, 7, 10, 2, 7, 8, 1, 3]
output = []

x = None
for y in range(len(data)):
  if y == len(data) - 1 or data[y] >= data[y+1]:
    output.extend(data[y:x:-1])
    x = y

print(output)
data = [5, 7, 10, 2, 7, 8, 1, 3,2]
def func(data):
    result =[]
    temp =[]
    data.append(data[-1])
    for i in range(1,len(data)):
        if data[i]>=data[i-1]:
            temp.append(data[i-1])
        else:
            temp.append(data[i-1])
            temp.reverse()
            result.extend(temp)
            temp=[]
    if len(temp)!=0:
        temp.reverse()
        result.extend(temp)
    temp.clear()
    return result

print(func(data))

# output [10, 7, 5, 8, 7, 2, 3, 1, 2] 

You could define a general handy method which returns slices of an array based on condition (predicate). 您可以定义一个通用的方法 ,它根据条件(谓词)返回数组的切片。

def slice_when(predicate, iterable):
  i, x, size = 0, 0, len(iterable)
  while i < size-1:
    if predicate(iterable[i], iterable[i+1]):
      yield iterable[x:i+1] 
      x = i + 1
    i += 1
  yield iterable[x:size] 


Now, the slice has to be made when the next element is smaller then the previous, for example: 现在,当下一个元素小于前一个元素时,必须进行切片,例如:

 array = [5, 7, 10, 2, 7, 8, 1, 3] slices = slice_when(lambda x,y: x > y, array) print(list(slices)) #=> [[5, 7, 10], [2, 7, 8], [1, 3]] 

So you can use it as simple as: 所以你可以像以下一样简单地使用它:

 res = [] for e in slice_when(lambda x,y: x > y, array): res.extend(e[::-1] ) res #=> [10, 7, 5, 8, 7, 2, 3, 1] 

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

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