1

I need to generate numpy arrays getting elements in reverse order from another array.

Toy example code

Lets say I use following toy example code:

import numpy as np
a = np.array([1,2,3,5,8,13])
n = len(a)

for i in range(n):
    print a[n:n-i-2:-1]

I would expect that last print is a [13 8 5 3 2 1], however I get an empty array [] as seen below:

>>> 
[13]
[13  8]
[13  8  5]
[13  8  5  3]
[13  8  5  3  2]
[]

Fix

So I had to create below fix to my code within the for loop to get what I expect.

for i in range(n):
    print a[n-i-1:n+1][::-1]

Which means selecting the arrays from the original array and then reversing it.

Questions

  1. Why when I try a[6:0:-1] I get [13, 8, 5, 3, 2] but once I try a[6:-1:-1] I get an emtpy array []? I would expect to get the whole array reversed as when you try a[::-1].
  2. Is the fix I implemented the way to go or there is something I'm missing here?

Edit

The post Understanding slice notation answers my first question but not the second one.

8
  • 2
    You might find this helpful stackoverflow.com/questions/509211/understanding-slice-notation Commented Jun 18, 2019 at 13:02
  • Possible duplicate of Understanding slice notation Commented Jun 18, 2019 at 13:05
  • What would you expect a[6:5:-1] to produce? Commented Jun 18, 2019 at 13:08
  • 1
    And -1 is a "shorthand" for the index of the last element (in this case, 5), so it should (and does) do the same. Commented Jun 18, 2019 at 13:26
  • 1
    @CedricZoppolo let me know if my answer helps Commented Jun 18, 2019 at 13:35

3 Answers 3

3

Here is a slightly more elegant fix.

for i in range(n):
    print(a[n:-i-2:-1])

or even more elegant

for i in range(n):
    print(a[:-i-2:-1])

both print

[13]
[13  8]
[13  8  5]
[13  8  5  3]
[13  8  5  3  2]
[13  8  5  3  2  1]

It also demonstrates the rule that negative indices count from the top, which is why your original loop switches behavior when the stop index gets to -1.

Sign up to request clarification or add additional context in comments.

1 Comment

This makes sense now.
1

Another option would be to use below code:

import numpy as np
a = np.array([1,2,3,5,8,13])
n = len(a)

l = range(n)
l[n-1] = None

for i in range(n):
    print a[n:l[n-i-2]:-1]

As performing a[n:None:-1] is same as a[::-1]

Comments

1

Use list comprehension and get the results in one line:

import numpy as np

a = np.array([1,2,3,5,8,13])
n = len(a)

# use list comprehension here
[list(a[n:-i-2:-1]) for i in range(n)]
# [[13],
#  [13, 8],
#  [13, 8, 5],
#  [13, 8, 5, 3],
#  [13, 8, 5, 3, 2],
#  [13, 8, 5, 3, 2, 1]]

In case you really need the exclicit for loop use this:

for i in range(n):
    print(a[n:-i-2:-1])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.