Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

index into Python dict with list to get a list, as with a Perl hash

Perl has a construct (called a "hash slice" as Joe Z points out) for indexing into a hash with a list to get a list, for example:

%bleah = (1 => 'a', 2 => 'b', 3 => 'c');
print join(' ', @bleah{1, 3}), "\n";

executed gives:

a c

the simplest, most readable way I know to approach this in Python would be a list comprehension:

>>> bleah = {1: 'a', 2: 'b', 3: 'c'}
>>> print ' '.join([bleah[n] for n in [1, 3]])
a c

because:

>>> bleah[[1, 2]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

is there some other, better way I'm missing? perhaps in Python3, with which I haven't done much yet? and if not, does anyone know if a PEP has already been submitted for this? my google-fu wasn't able to find one.

"it isn't Pythonic": yes, I know, but I'd like it to be. it is concise and readable, and since it will never be Pythonic to index into a dict with an unhashable type, having the exception handler iterate over the index for you instead of barfing wouldn't break most current code.

note: as was pointed out in comments, this test case could be rewritten as a list, obviating use of a dict altogether, but I'm looking for a general solution.

like image 602
jcomeau_ictx Avatar asked Dec 12 '13 03:12

jcomeau_ictx


1 Answers

The best way I could think of, is to use itemgetter

from operator import itemgetter
bleah = {1: 'a', 2: 'b', 3: 'c'}
getitems = itemgetter(1, 3)
print getitems(bleah)

So, if you want to pass a list of indices then you can unpack the arguments, like this (Thanks @koffein for pointing this out :))

getitems = itemgetter(*[1, 3])

You can then join like this

print ' '.join(getitems(bleah))

or simply

print ' '.join(itemgetter(1, 3)(bleah))
like image 79
thefourtheye Avatar answered Oct 24 '22 01:10

thefourtheye