列表中的反向升序

时间:2019-03-05 04:29:52

标签: python python-3.x list

试图弄清楚如何反转列表中的多个升序。

例如:input = [1,2,2,3]output = [2,1,3,2]

我已经使用过mylist.reverse(),但是它当然会反转为[3,2,2,1]。不确定采用哪种方法?

详细示例:

因此,可以说[5, 7, 10, 2, 7, 8, 1, 3]是输入-输出应该是[10,7,5,8,7,2,3,1]。在该示例中,前三个元素5,7,10处于升序,2,7,8同样以升序,而1,3也处于升序。该功能应该能够识别此模式并反转每个序列并返回一个新列表。

5 个答案:

答案 0 :(得分:1)

您需要找到所有非递减子序列并将其反转:

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]

要增加子序列,您需要将if l[idx] >= l[idx - 1]更改为if l[idx] > l[idx - 1]

答案 1 :(得分:1)

可能有一种更优雅的方法,但是一种方法是使用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]

答案 2 :(得分:1)

沿着列表走,从x位置到y位置的窗口越来越大。当您找到下一个数字不升序或到达末尾的位置时,请对刚刚覆盖的窗口进行切片,然后将其添加到输出列表的末尾:

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)

答案 3 :(得分:0)

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] 

答案 4 :(得分:0)

您可以定义一个常规方法,该方法根据条件(谓词)返回数组的切片。

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] 


现在,必须在下一个元素小于前一个元素时进行切片,例如:

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

因此,您可以像使用它一样简单:

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]