views:

334

answers:

3

I have the following code which I use to map a nested list in Python to produce a list with the same structure.

>>> nested_list = [['Hello', 'World'], ['Goodbye', 'World']]
>>> [map(str.upper, x) for x in nested_list]
[['HELLO', 'WORLD'], ['GOODBYE', 'WORLD']]

Can this be done with list comprehension alone (without using the map function)?

+4  A: 

For nested lists you can use nested list comprehensions:

nested_list = [[s.upper() for s in xs] for xs in nested_list]

Personally I find map to be cleaner in this situation, even though I almost always prefer list comprehensions. So it's really your call, since either will work.

Eli Courtwright
Ah of course. I must be more tired than usual.
kjfletch
in py3k map requires a list to be applied to it.
SilentGhost
+1  A: 

Map is certainly a much cleaner way of doing what you want. You can nest the list comprehensions though, maybe that's what you're after?

[[ix.upper() for ix in x] for x in nested_list]
KayEss
Yes, it may be cleaner using map but I would like to use a generator.
kjfletch
A: 

Other posters have given the answer, but whenever I'm having trouble wrapping my head around a functional construct, I swallow my pride and spell it out longhand with explicitly non-optimal methods and/or objects. You said you wanted to end up with a generator, so:

for xs in n_l:
    def doUpper(l):
        for x in l:
            yield x.upper()
    yield doUpper(xs)

for xs in n_l:
    yield (x.upper() for x in xs)

((x.upper() for x in xs) for xs in n_l)

Sometimes it's cleaner to keep one of the longhand versions. For me, map and reduce sometimes make it more obvious, but Python idioms might be more obvious for others.

Karl Anderson