Searching through a list of tuples

R

Repton

I often find myself storing data in a list of tuples, and I want to ask
questions like "what is the index of the first tuple whose 3rd element
is x", or "give me the first tuple whose 2nd element is y".

I know I can do [elem for elem in lst if elem[3] == x][0] or (elem for
elem in lst if elem[2] == y).next() but it feels kinda ugly; is there a
better way?

(something like lst.index(x, key=..) or lst.find(y, key=..) would be
nice)
 
P

Peter Hansen

Repton said:
I often find myself storing data in a list of tuples, and I want to ask
questions like "what is the index of the first tuple whose 3rd element
is x", or "give me the first tuple whose 2nd element is y".

I know I can do [elem for elem in lst if elem[3] == x][0] or (elem for
elem in lst if elem[2] == y).next() but it feels kinda ugly; is there a
better way?

(something like lst.index(x, key=..) or lst.find(y, key=..) would be
nice)

If the latter form would make you happy, why not just write a simple
utility function that does what you want (by using the first technique,
if you wish), and then calling it will be as simple as lst.index(....)

And no, since you are basically doing a form of pattern matching, I
don't think there's a shortcut.

-Peter
 
P

Peter Otten

Repton said:
I often find myself storing data in a list of tuples, and I want to ask
questions like "what is the index of the first tuple whose 3rd element
is x", or "give me the first tuple whose 2nd element is y".

I know I can do [elem for elem in lst if elem[3] == x][0] or (elem for
elem in lst if elem[2] == y).next() but it feels kinda ugly; is there a
better way?

(something like lst.index(x, key=..) or lst.find(y, key=..) would be
nice)
items = [(1, "a", 10), (2, "b", 20), (3, "c", 30)]
class Key(object):
.... def __init__(self, key):
.... self.key = key
.... def __eq__(self, other):
.... return self.key(other)
....
items.index(Key(lambda x: x[2] == 20)) 1
items.index(Key(lambda x: x[1] == "c"))
2

A cleaner and probably faster solution would be to subclass list and
override index()/find().

Peter
 
S

Scott David Daniels

iter(n for n, elem in enumerate(lst) if elem[3] == x).next()
iter(elem in lst if elem[3] == x).next()

Does this look any better? At least it stops when the answer is found.

--Scott David Daniels
(e-mail address removed)
 
A

Alan Green

Peter said:
Repton said:
I often find myself storing data in a list of tuples, and I want to ask
questions like "what is the index of the first tuple whose 3rd element
is x", or "give me the first tuple whose 2nd element is y".
items = [(1, "a", 10), (2, "b", 20), (3, "c", 30)]
class Key(object):
... def __init__(self, key):
... self.key = key
... def __eq__(self, other):
... return self.key(other)
...
items.index(Key(lambda x: x[2] == 20))
1

Neat solution.

I'd add an extra kind of Key, since finding tuples where a given
position is equal to a given value seems to be the common case:
.... def __init__(self, pos, val):
.... super(EqualKey, self).__init__(lambda x: x[pos] == val)
.... 1

Alan
 
P

Peter Otten

Scott said:
iter(elem in lst if elem[3] == x).next()

Does this look any better?  At least it stops when the answer is found.

Next time you'll recommend

if (a>b) == True:
# ...

Watch out, you're on a slippery slope here :)

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top