0

Let's say I have a list of lists like this

lol = [[1, 'e_r_i'], [2, 't_u_p']]

and I want to apply a function to the string elements which returns several values from which I need only a subset (which ones differ per use-case). For illustration purposes, I just make a simple split() operation:

def dummy(s):
    return s.split('_')

Now, let's say I only want the last two letters and concatenate those; there is the straightforward option

positions = []
for _, s in lol:
    stuff = dummy(s)
    positions.append(f"{stuff[1]}{stuff[2]}")

and doing the same in a list comprehension

print([f"{dummy(s)[1]}{dummy(s)[2]}" for _, s in lol])

both give the identical, desired outcome

['ri', 'up']

Is there a way to use the walrus operator here in the list comprehension to avoid calling dummy twice?

PS: Needless to say that in reality the dummy function is far more complex, so I don't look for a better solution regarding the split but it is fully about the structure and potential usage of the walrus operator.

Cleb
  • 20,118
  • 16
  • 91
  • 131

2 Answers2

3

I will have to say that your first explicit loop is the best option here. It is clear, readable code and you're not repeating any calls.

Still, as you asked for it, you could always do:

print([f"{(y:=dummy(s))[1]}{y[2]}" for _, s in lol])

You could also wrap the processing in another function:

def dummy2(l):
    return f"{l[1]}{l[2]}"

And this removes the need of walrus altogether and simplifies the code further:

print([dummy2(dummy(s)) for _, s in lol])
Tomerikoo
  • 12,112
  • 9
  • 27
  • 37
1

Yes. This is what you want

output = [f"{(stuff := dummy(s))[1]}{stuff[2]}" for _, s in lol]
GZ0
  • 3,288
  • 1
  • 4
  • 19