othymomo
othymomo

Reputation: 105

modify list elements on a condition

I am new to Python but have C/C++ background. I am trying to modify a 2D list (list of lists) elements that satisfy a condition. All I could come up with is the following solution:

tsdata = [[random.random() for x in range(5)] for y in range(5)]
def check(tsdata):
    for i in range(len(tsdata)):
        for j in range(len(tsdata[i])):
            if (tsdata[i][j] < min_value) or (tsdata[i][j]> max_value):
                tsdata[i][j] = 0
check(tsdata)

I am sure there is a better solution which is actually suitable for Python but can't think of anything else that actually works.

EDIT: Actually, the list tsdata is a function argument and I am trying to modify it so some of your answers do not work. I have edited the code so this is clear.

Upvotes: 0

Views: 4107

Answers (3)

Ma0
Ma0

Reputation: 15204

Welcome to the world of simplicity and compact statements.

tsdata_mod = [[0 if (x < min_value or x > max_value) else x for x in y] for y in tsdata]

or in function mode:

def check(my_list):
    my_list_mod = [[0 if (x < min_value or x > max_value) else x for x in y] for y in tsdata]
    return my_list_mod

tsdata_mod = check(tsdata)

The above is in my opinion a very "pythonic" way to go about this task.


Also when looping through containers such as lists for example you don't do:

for i in range(len(tsdata)):
    for j in range(len(tsdata[i])):
        # do something with "tsdata[i]","tsdata[i][j]"

But rather:

for sublist in tsdata:
    for entry in sublist:
        # do something with "sublist", "entry"

And if you really need the indexes (which in your case you don't) you use the enumerate() function like so:

for i_sub, sublist in enumerate(tsdata):
    for i_entry, entry in enumerate(sublist):
        # do something with "i_sub", "sublist", "i_entry", "entry"

Upvotes: 0

Mikael Rousson
Mikael Rousson

Reputation: 2267

If you want to handle big arrays, you may want to use numpy. Besides being much more efficient, I think the code is easier to read:

from numpy import random
tsdata = random.random((5, 5))
tsdata[tsdata < min_value] = 0
tsdata[tsdata > max_value] = 0

Upvotes: 3

aluriak
aluriak

Reputation: 5847

Your solution is not bad, but the following could be more simpler to understand. (depends of how your code should evolve later)

def new_value(value):
    """Encapsulation of the core treatment"""
    return 0 if (value < min_value) or (value > max_value) else value

new_tsdata = [[new_value(value) for value in row] for row in ts_data]

In python, you should seek for new objects instead of existing object modification.

Upvotes: 0

Related Questions