Search code examples
pythonarraysfor-loopif-statementnested-lists

Changing Specific Values In a 2D array Using For Loops and If statements without a known Index


I have a 2D array from a geotiff file. See the example array below:

example_array = [[ 0, 1, 1, 0, 0, 0, 0], 
                 [ 2, 1, 1, 2, 0, 0, 0], 
                 [ 0, 3, 1, 1, 3, 0, 0], 
                 [ 4, 1, 1, 4, 0, 0, 0], 
                 [ 0, 5, 1, 1, 5, 0, 0], 
                 [ 0, 1, 1, 0, 0, 0, 0]]

I am attempting to write a program that will change the specific number greater than 1 in each nested list to the 'value + 100'.

With the help of others see the below working code snippet that correctly changes the first value in each list greater than 1 to +100 of the value.

for l in example_array:
    for i, x in enumerate(l):
        if x > 1:
            l[i] -= 100
            break

If I wanted to change exclusively the second value in each list greater than 1 I attempted the below incorrect code snippet:

for l in example_array:
    for i, x in enumerate(l):
        if x > 1:
            if x > 1:
                l[i] -= 100
                break 

The thought process here is that if I added another if x>1: argument to the for loop it would start at the first number greater than 1 then move to the second value greater than 1 with the next if x>1:. That is not the case here. Does anyone have any suggestions on how to correctly change the second number greater that 1 such that is displays the correct example_array below?:

    example_array = [[ 0,  1, 101, 0, 0, 0, 0], 
                     [ 2, 101, 1,  2, 0, 0, 0], 
                     [ 0,  3, 101, 1, 3, 0, 0], 
                     [ 4, 101, 1,  4, 0, 0, 0], 
                     [ 0,  5, 101, 1, 5, 0, 0], 
                     [ 0,  1, 101, 0, 0, 0, 0]]

Solution

  • I assumed for this response that you meant >=1 and not >1, judging by the final example you provided.

    this is not the pretties solution but i guess it is what you're looking for:

    for l in example_array:
        c = 0
        for i, x in enumerate(l):
            if x >= 1:
                if c == 1:
                    l[i] += 100
                    break
                c += 1
    

    However you can do it much more efficiently using numpy:

    import numpy as np
    
    # Assuming example_array is a list of lists
    for row in example_array:
        row_np = np.array(row)  # Convert list to NumPy array for the comparison
        positive_indices = np.where(row_np >= 1)[0]  # Get indices of elements greater than or equal to 1
        if len(positive_indices) >= 2:  # Check if there are at least two elements greater than or equal to 1
            row[positive_indices[1]] += 100  # Add 100 to the second element greater than or equal to 1