KKL
KKL

Reputation: 85

How to replace item in a list to empty string based on another nested list of same length based on condition

I have a header list as below:

h_list = ['h1','h2','h3','h4','h5']

Now I have data list (Nested):

d_list = [
[1, None, 3, ' ', 5],
[1, ' ', 2, ' ', 9]
]

Both lists are of same length every time, so I want to match in each list of nested list at same index position and if its all corresponding values are either None or ' ', then replace the item from h_list to ' ' (Empty string)

My expected output is:

h_list = ['h1',' ','h3',' ','h5']

Upvotes: 3

Views: 648

Answers (4)

Ajax1234
Ajax1234

Reputation: 71451

You can use zip with all:

h_list = ['h1','h2','h3','h4','h5']
d_list = [[1, None, 3, ' ', 5], [1, ' ', 2, ' ', 9]]
r = [' ' if all(k in {None, ' '} for k in j) else a for a, j in zip(h_list, zip(*d_list))]

Output:

['h1', ' ', 'h3', ' ', 'h5']

Upvotes: 1

Red
Red

Reputation: 27547

Try a list comprehension:

h_list = ['h1','h2','h3','h4','h5']


d_list = [
[1, None, 3, ' ', 5],
[1, ' ', 2, ' ', 9]
]

empty = [' ', None]
h_list = [' ' if any(b[i] in empty for b in d_list) else v for i, v in enumerate(h_list)]
print(h_list)

Output:

['h1', ' ', 'h3', ' ', 'h5']

Breaking down this part of the code:

h_list = [' ' if any(b[i] in empty for b in d_list) else v for i, v in enumerate(h_list)]

First, lets have only

[(i, v) for i, v in enumerate(h_list)]

The above will be a list of the indices and values of each element in h_list.

Now, we use an if statement to determine when to add the ' '. First, we need to recognize the any() function:

any(b[i] in empty for b in d_list)

returns True if any of the arrays inside d_list at index i is in the empty list. We want None and ' ' to be in place for all the strings in h_list that its index returns a ' ' or None for any of the lists in d_list, so:

[' ' for i, v in enumerate(h_list) if any(b[i] in empty for b in d_list)]

Finally, we want to use the original string if not any(b[i] in empty for b in d_list). For that, we use an else statement (note that with an else, the statements get shifted to the left side of the for loop.):

h_list = [' ' if any(b[i] in empty for b in d_list) else v for i, v in enumerate(h_list)]

Upvotes: 4

ombk
ombk

Reputation: 2111

Basic solution

h_list = ['h1','h2','h3','h4','h5']
d_list = [
[1, None, 3, ' ', 5],
[1, ' ', 2, ' ', 9]
]
# loop over d_list
for i in d_list:
# loop over inner list 
    for k in i:
# if type not int, give me space in that index
        if type(k)!=int:
            h_list[i.index(k)]=" "
h_list

Upvotes: 0

GACy20
GACy20

Reputation: 979

I believe this should work for your examples:

new_list = []
for orig_element, *values in zip(h_list, *d_list):
    new_list.append(orig_element if any(not (v is None or str(v).strip() == '') for v in values) else '')

If you want to modify the list in-place simply do:

for i, (orig_element, *values) in enumerate(h_list, *d_list):
    h_list[i] = orig_element if any(not (v is None or str(v).strip() == '') for v in values) else ''

Upvotes: 2

Related Questions