0

I have a list of tuples

student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]

I've been trying different ways to sort this, using itemgetter and lambda functions. Sorting by two indices of the tuples can be done with itemgetting and the lambda function, but it must return a tuple. I can't seem to find that anywhere in the documentation that the key function works on tuples.

Anyway, I wanted to know what itemgetter() actually returns, so this works (copied from the itemgetter documentation):

f = itemgetter(1)
print f(student_tuples[0])
----->A

Is there any way to do this WITHOUT having to reassign itemgetter to a variable? It looks like two arguments are being passed, but something like

print itemgetter(1, student_tuples[0])
-----><operator.itemgetter object at 0xf7309c8c>

doesn't give me anything useful.

I'm just fiddling around trying to learn Python and this is confusing me. I don't know where in itemgetter student_tuples[0] is being added as an argument.

2 Answers 2

3

The return value of itemgetter(1) is a function (actually, a callable object, but it's used like a function).

The function it returns is roughly equivalent to the function that results from the expression:

lambda x: x[1]

student_tuples[0] isn't added as an argument anywhere in itemgetter. It is passed as an argument to the function-that-was-returned when you call f(student_tuples[0]).

Since f is the result of itemgetter(1), it follows that you can do this in one line as:

itemgetter(1)(student_tuples[0])
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that cleared it up. Is it generally better to use itemgetter, attrgetter, etc, or are using lambda functions OK to use? They both seem fairly compact in the context of sorting, but I'm a newbie so maybe there are other uses where itemgetter is far superior.
@jktstance: personally I don't think there's much in it, but some people strongly dislike lambdas and argue that there's no need for them in the language in the first place. I generally wouldn't import operator just for a single use of itemgetter, but if I'm using operator anyway then I figure it's worth it. In some cases you might also want to compare the performance of the two and pick the faster.
2

You need to call the return value of itemgetter() again, not pass in the list as the second argument. Example -

itemgetter(1)(student_tuples[0])

As can be seen from the documentation -

operator.itemgetter(*items)

Return a callable object that fetches item from its operand using the operand’s __getitem__() method.

itemgetter() returns a function, which you can again call passing in the actual iterable, to get the value from that particular index in that iterable.

When you pass in multiple values to itemgetter() , it still returns a function, and calling that function would try to get the elements from the iterable using the index you passed in to itemgetter() initially as a tuple. Example -

>>> l =[1,2,3,4,5]
>>> operator.itemgetter(1,2,4)(l)
(2, 3, 5)

Comments

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.