Searching through a list of tuples

Discussion in 'Python' started by Repton, Jul 12, 2005.

  1. Repton

    Repton Guest

    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)

    --
    John.
     
    Repton, Jul 12, 2005
    #1
    1. Advertising

  2. Repton

    Peter Hansen Guest

    Repton wrote:
    > 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
     
    Peter Hansen, Jul 12, 2005
    #2
    1. Advertising

  3. Repton

    Peter Otten Guest

    Repton wrote:

    > 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
     
    Peter Otten, Jul 12, 2005
    #3
  4. Peter Otten wrote:
    > Repton wrote:
    >
    >>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",

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

    >>or "give me the first tuple whose 2nd element is y".

    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
     
    Scott David Daniels, Jul 12, 2005
    #4
  5. Repton

    Alan Green Guest

    Peter Otten wrote:
    > Repton wrote:
    >
    > > 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:

    >>> class EqualKey(Key):

    .... def __init__(self, pos, val):
    .... super(EqualKey, self).__init__(lambda x: x[pos] == val)
    ....
    >>> items.index(EqualKey(2, 20))

    1

    Alan
     
    Alan Green, Jul 12, 2005
    #5
  6. Repton

    Peter Otten Guest

    Scott David Daniels wrote:

    > 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
     
    Peter Otten, Jul 13, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    5
    Views:
    581
    Thomas J. Gritzan
    Oct 6, 2006
  2. tuples within tuples

    , Oct 26, 2007, in forum: Python
    Replies:
    12
    Views:
    620
    Dennis Lee Bieber
    Oct 27, 2007
  3. xera121
    Replies:
    8
    Views:
    762
    lolmc
    Sep 30, 2009
  4. Jon Reyes
    Replies:
    18
    Views:
    274
    Mitya Sirenef
    Feb 19, 2013
  5. Shyam Parimal Katti

    Iterate through a list of tuples for processing

    Shyam Parimal Katti, Sep 20, 2013, in forum: Python
    Replies:
    0
    Views:
    115
    Shyam Parimal Katti
    Sep 20, 2013
Loading...

Share This Page