Reverse order sequential digits

  • A+
Category:Languages

I have a very long array, and I'm trying to do the following in a way as efficient as possible:

For each consecutively incrementing chunk in the list I have to reverse its order.

So, for the following array:

a = np.array([1,5,7,3,2,5,4,45,1,5,10,12]) 

I would like to obtain:

array([7,5,1,3,5,2,45,4,12,10,5,1]) 

I was wondering if this could be vectorized, using numpy perhaps?

I have already had some answers in this previous question, but the results, although they are big improvements, they are still a little slow.

 


Other option without dependencies:

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] 


Modified version which is a bit faster:

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 


EDIT after the answer was accepted (Maybe it's useful.)

I was able to get the result so easily and apparently a bit faster coding in Ruby as:

array.chunk_while { |x, y| x < y }.flat_map{ |chunk| chunk.reverse } 

So, I wondered why there isn't an itertool like chunk_while. Then I tried to code one similar using 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] 

The execution is superfast but it return a generator to iterate instead of a list:

chunks = reverse_if_chunk_increases(array) for chunk in chunks:   print(chunk) # [7, 5, 1] # [3] # [5, 2] # [45, 4] # [12, 10, 5, 1] 

It can be converted to a list, which is the slowest process. Note that a generator can be called once. Removing [::-1] you get a result similar to Ruby enumerator/generator chunk_while.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: