0

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]

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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']]

1 Comment

This will also replace 0.
0

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]])

1 Comment

I believe this is the same for loop solution I put in the OP. I was trying to find a list comprehension to do the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.