I was recently working on this question. Essentially, my answer involved a call to sorted with a lambda as the key:
sorted(range(len(L)), key=lambda i : L[i])
Given that performance was at the core of the question, and that lambdas are inherently slow, I could have optimized a bit by defining a function and using it in place of the lambda.
Still, I feel that that I’d be reinventing the wheel. There has to be a built-in function somewhere or in some importable module that provides the functionality of __getitem__ (which, the only reason I don’t want to use, is that it’s not really pythonic to use mangled methods).
I know about operator.getitem which let’s me predefine an index i and get the element at i in any input sequence. But is there a function (say foo) that works as follows:
In [14]: g = operator.itemgetter(1)
In [15]: d = {'a':1, 'b':2, 'c':3, 'd':4}
In [16]: for i in d.iteritems():
....: print g(i),
....:
1 3 2 4
In [17]: L = list('abcd')
In [18]: g = foo(L)
In [19]: for i in range(4):
....: print g(i),
....:
'a' 'b' 'c' 'd'
Sorry if this is a duplicate question, but the search words that I could think of did not yield results.
If I’ve understood what you want correctly, the following would do that:
Update:
I’ve experimented further and was surprised to discover a slightly faster solution, which is this nothing other than simply this:
Which, when run using a little testbed I threw together, produced the following results:
Each test function used just access each element of a list in a tight loop using a different technique.
Curious about how this applied to your sorting answer to the linked question, I obtained these differing results using it for sorting a list rather than just accessing each of the list’s elements once:
While
foo2()was the fastest In both cases, in the sorting version it was only so by a very small amount.Here’s a listing of the full testbed used to get the first set of results for simple access:
And here’s the portion that was different when testing sort usage: