1

I've just been learning lambda (About time) and I've figured some things out, I get the general idea.

I have a map() with a lambda here that can surely be made shorter, but I don't know how:

map(lambda x: [ x.split()[0], x.split()[2], x.split()[4] ] , y)

I hoped it would be possible to get the 0, 2 and 4 elements of the split 'x' at once, but currently I have to split it 3 times to get them...

2
  • Note that you almost never actually want to use map; it's almost completely obsoleted by list comprehensions. If you're reading a tutorial that's telling you to use it, it's probably very old and may be teaching you bad habits. The clean way of writing this (starting from @Yuval's answer) is [x.split()[0:5:2] for x in y]. Commented Nov 14, 2010 at 13:51
  • 1
    Yes, but this is just me tinkering with lambda so for the purposes of learning. Commented Nov 14, 2010 at 13:55

3 Answers 3

6
lambda x: operator.itemgetter(0, 2, 4)(x.split())
Sign up to request clarification or add additional context in comments.

13 Comments

I assume that's supposed to be operator.itemgetter?
@delnan: Pfft. Yes. That's what happens when I'm not awake.
I like both, but this one gives more control over which ones I want, is there a non-itemgetter() way to do it with the list syntax alone?
No. list does not support arbitrary sequences of indexes.
list does not support arbitrary sequences of indexes.
|
4

map(lambda x: x.split()[0:5:2] , y)

Meaning - take x.split() and take the sublist [0:5] with each second item in it.

1 Comment

[0:4:2] will only give the first two. Try [0:5:2]
1

Just for variety's sake, featuring no itemgetter() call:

    map(lambda x: [x[i] for i in (0,2,4)], (s.split() for s in y))

The (0,2,4) could be replaced with range(0,5,2), of course.
For such a small number of items you could just be explicit with: [x[0], x[2], x[4]]

How it works: The lambda function simply returns a list of the desired elements of the list it is passed. The (s.split() for s in y) is a generator that produces split() versions of the items in list y. Driving all this is the call to map() which applies the lambda function to each one of the split() items from y. In Python 2.x it creates a list of the results from each of these calls.

To answer your follow-up question in the comments about using g = lambda x: [x[i] for i in (0,2,4)] along with (g(s.split()) for s in y) to get rid of map(). That's basically the right idea, but the second expression results in just a generator object. That would need to be wrapped in something like: [g(s.split()) for s in y] to get the result.

If you didn't want to have a separate lambda named g you could use:

    [(lambda x: [x[i] for i in (0,2,4)])(s.split()) for s in y]

5 Comments

Theres what I was looking for, but I don't see just how it works :/ Also, wouldn't this mean map() is only iterating once and that the for loop does the work? Can't we just get rid of map() somehow this way?
You said you wanted to use a lambda function, so something will have to call it and map is the obvious choice. If you don't want to use lambda, as @Glenn Maynard said, list comprehensions are the way to go.
What about something like: lambda x: [x[i] for i in (0,2,4)] (s.split() for s in y)
No, the result of that expression is just a lambda function: such as <function <lambda> at 0x00AD44F0>. Something else needs to call the function multiple times and collect the results. That's why map() is used.
Ok, I see... Is it possible to say: g = lambda x: [x[i] for i in (0,2,4)] then later on: (g(s.split()) for s in y)

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.