-1

I have an array that I would like to iterate over and modify the array itself, through inserts or deletions.

for idx, ele in enumerate(np.nditer(array)):
  if idx + 1 < array.shape[0] and ele > array[idx+1]:
    array = np.delete(array, idx+1)
  print(ele)

Given [5, 4, 3, 2, 1] I want the loop to print out 5 3 1 because 4 and 2 are smaller than their previous elements. But because python creates an iterator based on the first instance of array so it prints 5 4 3 2 1. I want to know if I can get

Generally speaking I want the iterator to be modified if I modify the array within the body of my loop.

20
  • Usually objects such as function, classes.. used from the standard library, or other third-party library should behave as the docs says. So you do not have to check their behavior in your code. Commented Nov 3, 2019 at 14:30
  • But you may mean something else, so please add more details to your question if so. Commented Nov 3, 2019 at 14:31
  • Your loop seems to do what you want - at least for that input. It isn't clear what you are asking. Commented Nov 3, 2019 at 14:33
  • 2
    "python creates iterable object by evaluating the array the first time." "the loop reevaluate the object" - sorry, this is word salad to me. We need an example with initial array, expected output and actual output. Commented Nov 3, 2019 at 15:16
  • 1
    @actual_panda. Thanks for the term "word salad". Commented Nov 3, 2019 at 15:25

2 Answers 2

2

You cannot mutate the length of a numpy array, because numpy assigns the required memory for an array upon its creation.

With

array = np.delete(array, idx+1)

You are creating a new array on the right hand side of the = and reassign the name array.

The return value for enumerate(np.nditer(array)) has already been created at that point and won't recognize that the name array has been rebound.

In principle, you can iterate over a sequence and mutate its length at the same time (generally not a good idea). The object just needs to have methods that let you mutate its length (like lists, for example).

Consider:

>>> l = [5, 4, 3, 2, 1]                                                         
>>> for idx, ele in enumerate(l): 
...:     if ele == 3: 
...:         l.pop(idx) # mutates l 
...:     print(ele) 
...:                                                                            
5
4
3
1
>>> l                                                                           
[5, 4, 2, 1]

Notice that

  1. l is mutated.
  2. The loop does not print 2 because popping an element reduces the indexes of all the remaining elements by one. Now l[2] == 2, but index 2 has already been visited by the iterator, so the next print-call prints l[3] which is 1.

This proves that mutations to l have effect on subsequent iterations.

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

Comments

0

Instead of looping over an array, you can use where method to find indices of elements meeting some condition.

Then to delete the selected element (or elements), you can use delete method, passing the source array, and a list of indices. Then save the result, e.g. under the same variable.

To add an element, you can use append or insert methods (for details see Numpy documentation).

I have also found a SO post concerning how to loop and delete over an array. See Deleting elements from numpy array with iteration

1 Comment

Please read my post carefully. I'm not referring to that specific example.

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.