1

I am implementing an algorithm which might affect the size of some array, and I need to iterate through the entire array. Basically a 'for x in arrayname' would not work because it does not update if the contents of arrayname are changed in the loop. I came up with an ugly solution which is shown in the following example:

test = np.array([1,2,3])
N = len(test)
ii=0
while ii < N:
    N = len(test)
    print(test[ii])
    if test[ii] ==2:
            test = np.append(test,4)
    ii+=1 

I am wondering whether a cleaner solution exists.

Thanks in advance!

Sub-Xel
  • 51
  • 3
  • Use a list comprehension to make a new list. If you must mutate the original list, do a slice assignment afterwards. – kaya3 Feb 13 '20 at 04:50
  • @kaya3 could you please give a concrete example? - how can it allow me to still iterate over the additional elements? – Sub-Xel Feb 13 '20 at 05:02
  • 1
    In this case you want to append a 4 for each 2 in the list so `arr.extend([4 for x in arr if x == 2])` does the same thing. In other cases it will be different, and it depends on whether you want to add or remove things from the list. That code is for a native Python list, not a numpy array, but [numpy is not the right thing to use](https://stackoverflow.com/a/13215559/12299000) when you want to do a lot of appends anyway; but if you must use numpy, concatenate instead of extend. – kaya3 Feb 13 '20 at 05:08

2 Answers2

0

The while loop seems the best solution. As the condition is re-evaluated at each iteration, you don’t need to reset the length of the list in the loop, you can do it inside the condition:

import random

l = [1, 2, 3, 4, 5]
i = 0
while i < len(l):
  if random.choice([True, False]):
    del l[i]
  else:
    i += 1

print(f'{l=}')

This example gives a blueprint for a more complex algorithm. Of course, in this simple case, it could be coded more simply with a filter, or like this:

l = [1, 2, 3, 4, 5]
[x for x in l if random.choice([True, False])]

You might want to check this related post for more creative solutions: How to remove items from a list while iterating?

kotchwane
  • 2,082
  • 1
  • 19
  • 24
0

Assuming all the elements are going to be added at the end and no elements are being deleted you could store the new elements in a separate list:

master_list = [1,2,3]
curr_elems = master_list
while len(curr_elems) > 0: # keep looping over new elements added
    new_elems = []
    for item in curr_elems: # loop over the current list of elements, initially the list but then all the added elements on second run etc
        if should_add_element(item):
            new_elems.append(generate_new_element(item))
    master_list.extend(new_elems) # add all the new elements to our master list
    curr_elems = new_elems # and prep to iterate over the new elements for next iteration of the while loop
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59