Другой вариант без зависимостей:
array = [1,5,7,3,2,5,4,45,1,5,10,12]
res, memo = [], []
for e in array:
if len(memo) == 0 or e > memo[-1]: memo.append(e)
else:
res.extend(reversed(memo))
memo = [e]
res.extend(reversed(memo))
res # => [7, 5, 1, 3, 5, 2, 45, 4, 12, 10, 5, 1]
Модифицированная версия, которая немного быстрее:
def reverse_if_chunck_increases(array):
res, memo, last_memo = [], [], None
for e in array:
if not last_memo or e > last_memo:
last_memo = e
memo.append(e)
else:
res.extend(memo[::-1])
last_memo, memo = e, [e]
res.extend(memo[::-1])
return res
print(reverse_if_chunck_increases(array) == [7, 5, 1, 3, 5, 2, 45, 4, 12, 10, 5, 1])
#=> True
РЕДАКТИРОВАТЬ после того, как ответ был принят (Может быть, это полезно.)
Мне удалось получить результат так же легко и, по-видимому, немного быстрее кодирования в Ruby:
array.chunk_while { |x, y| x < y }.flat_map{ |chunk| chunk.reverse }
Итак, я удивляюсь, почему не существует itertool
, как chunk_while
. Затем я попытался закодировать один подобный, используя yield
:
def reverse_if_chunk_increases(array):
i, x, size, res = 0, 0, len(array), []
while i < size-1:
if array[i] > array[i+1]:
yield array[x:i+1][::-1]
x = i +1
i += 1
yield array[x:size][::-1]
Выполнение выполняется очень быстро, но вместо списка возвращается генератор для итерации:
chunks = reverse_if_chunk_increases(array)
for chunk in chunks:
print(chunk)
# [7, 5, 1]
# [3]
# [5, 2]
# [45, 4]
# [12, 10, 5, 1]
Его можно преобразовать в список, который является самым медленным процессом.
Обратите внимание, что генератор можно вызвать один раз.
При удалении [::-1]
вы получите результат, аналогичный перечислителю / генератору Ruby chunk_while
.