ThousandFacedHero
ThousandFacedHero

Reputation: 3

Python - Replace specific element in nested list comprehension

Preface: I realized this is just me being obsessed with making something more pythonic.

I have a list of lists like such:

L = [[1,'',3,''],[1,2,'',4],[1,2,3,''],['',2,3,4]]

I need to replace ONLY the 4th element with the number 4 IF it is ' '.

This can be achieved with a simple for loop:

for row in L:
    if row[3] =='':
        row[3] = 4

How can I achieve this through a nested list comprehension?

My best attempt is the following, but it results in a list of lists that have all values of ' ' replaced with 4, rather than the specific element.

L = [[4 if x=='' else x for x in y] for y in L]

Upvotes: 0

Views: 2592

Answers (3)

Ankan Roy
Ankan Roy

Reputation: 17

There is no need to put two for loops , this can be achieved with one loop only

def lis(L):
    for y in L:
        if y[3] == '':
            y[3] = 4
print L

lis([[1,'',3,''],[1,2,'',4],[1,2,3,''],['',2,3,4]])

Upvotes: 0

zwer
zwer

Reputation: 25829

This can be done in a very simple manner, and quite performant to boot (executes in O(N) time almost entirely on the C side), if all your sublists are of the same length:

L = [[1, '', 3, ''], [1, 2, '', 4], [1, 2, 3, ''], ['', 2, 3, 4]]

L2 = [[e0, e1, e2, 4 if e3 == "" else e3] for e0, e1, e2, e3 in L]
# [[1, '', 3, 4], [1, 2, '', 4], [1, 2, 3, 4], ['', 2, 3, 4]]

However, Pythonic is an illusive term and means different things to different people - cramming everything into an one-liner is not necessarily 'Pythonic'.

UPDATE - Actually, going on the same track, you can make it sub-list size agnostic, and replace the last element without knowing upfront the number of elements or if they even differ:

L = [[1, '', 3, ''], [1, 2, ''], [1, 2, 3, '', 5], ['', 2, 3, 4, 5, '']]

L2 = L2 = [e[:-1] + ["FOO" if e[-1] == "" else e[-1]] for e in L]
# [[1, '', 3, 'FOO'], [1, 2, 'FOO'], [1, 2, 3, '', 5], ['', 2, 3, 4, 5, 'FOO']]

Upvotes: 0

Ajax1234
Ajax1234

Reputation: 71471

You can try this:

L = [[1,'',3,''],[1,2,'',4],[1,2,3,''],['',2,3,4]]

new_l = [[4 if b == '' and c == 3 else b for c, b in enumerate(d)] for d in L] 

Output:

[[1, '', 3, 4], [1, 2, '', 4], [1, 2, 3, 4], ['', 2, 3, 4]]

By using enumerate, you can determine if both the element itself is equal to '' and verify that the index of the occurrence is 3, which is the fourth element.

Upvotes: 2

Related Questions