44

Is it possible to get Value out of tuple:

TUPLE = (
    ('P', 'Shtg1'),
    ('R', u'Shtg2'),
    ('D', 'Shtg3'),
)

by calling STR key like P

Python says that only int can be used for this type of 'query'

I can't use loop (too much overhead...)

Thank you!

Mission
  • 1,287
  • 3
  • 16
  • 31
  • 3
    There's no other way than looping sequentially until you find the key with a data structure like this one. If you don't want that, then you need a mapping (in Python it uses a hash-table for constant-time lookup). You can easily turn this into a `dict` by saying `dict(TUPLE)`. – Cat Plus Plus Jan 04 '12 at 17:34
  • [`namedtuple`](http://docs.python.org/library/collections.html#collections.namedtuple) can be used for this. See Eduardo's answer and my elaboration. – cod3monk3y Sep 05 '14 at 14:22

5 Answers5

66

The canonical data structure for this type of queries is a dictionary:

In [1]: t = (
   ...:     ('P', 'Shtg1'),
   ...:     ('R', u'Shtg2'),
   ...:     ('D', 'Shtg3'),
   ...: )

In [2]: d = dict(t)

In [3]: d['P']
Out[3]: 'Shtg1'

If you use a tuple, there is no way to avoid looping (either explicit or implicit).

NPE
  • 486,780
  • 108
  • 951
  • 1,012
16

dict(TUPLE)[key] will do what you want.

There is a little memory overhead, but it's fast.

Koed00
  • 651
  • 7
  • 7
  • Can you think of a way to do this with multiple keys? E.g. if the original code was `foo, bar = TUPLE`, is there an idiomatic way to unpack a `namedtuple` into multiple variables based on keys? This is obviously incorrect but something like `foo, bar = dict(TUPLE)["foo", "bar"]` – davidA Feb 27 '17 at 01:30
9

You want to use a dictionary instead.

d = { 'P': 'Shtg1', 'R': u'Shtg2', 'D':'Shtg3' }

And then you can access the key like so:

d['P'] # Gets 'Shtg1'
Makoto
  • 104,088
  • 27
  • 192
  • 230
7

Instead of moving to full dictionaries you can try using a named tuple instead. More information in this question.

Basically you define tags for the fields and then are able to refer to them as value.tag1, etc.

Quoting the docs:

Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.

Community
  • 1
  • 1
Eduardo Ivanec
  • 11,668
  • 2
  • 39
  • 42
4

To elaborate on Eduardo's answer with some code from the python shell.

>>> from collections import namedtuple
>>> MyType = namedtuple('MyType', ['P', 'R', 'D'])
>>> TUPLE = MyType(P='Shtg1', R=u'Shtg2', D='Shtg3')
>>> TUPLE
MyType(P='Shtg1', R=u'Shtg2', D='Shtg3')

>>> TUPLE.P
'Shtg1'

>>> TUPLE.R
u'Shtg2'

>>> TUPLE.D
'Shtg3'

>>> TUPLE[0:]
('Shtg1', u'Shtg2', 'Shtg3')

Remember that tuples are immutable, and dictionaries are mutable. If you want immutable types, namedtuple might be the way to go.

cod3monk3y
  • 9,508
  • 6
  • 39
  • 54