обратные восходящие последовательности в списке - PullRequest
0 голосов
/ 05 марта 2019

Попытка выяснить, как изменить несколько восходящих последовательностей в списке.

Например: 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].В этом примере первые 3 элемента 5,7,10 расположены в порядке возрастания, 2,7,8 также в порядке возрастания и 1,3 также в порядке возрастания.Функция должна быть в состоянии распознать этот шаблон, обратить каждую последовательность и вернуть новый список.

Ответы [ 5 ]

0 голосов
/ 05 марта 2019

Вы можете определить общий удобный метод , который возвращает срезы массива на основе условия (предиката).

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]
0 голосов
/ 05 марта 2019
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] 
0 голосов
/ 05 марта 2019

Вероятно, есть более элегантный способ сделать это, но один из подходов заключается в использовании itertools.zip_longest вместе с enumerate для перебора последовательных пар элементов в вашем списке и отслеживания каждого индексагде последовательность больше не возрастает или список исчерпан для того, чтобы разрезать, развернуть и расширить свой выходной список с нарезанными элементами.

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]
0 голосов
/ 05 марта 2019

Пройдитесь по списку, создавая все большее и большее окно от 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)
0 голосов
/ 05 марта 2019

Все, что вам нужно, это найти все неубывающие подпоследовательности и обратить их вспять:

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]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...