Extracting item from list of tuples?

Discussion in 'Python' started by Roy Smith, Sep 5, 2010.

  1. Roy Smith

    Roy Smith Guest

    I'm using httplib, and want to get the Location header from the
    response. The getheaders() method gives you back a list of (name,
    value) tuples. It would be a lot more convenient if it gave you back a
    dict, but it is what it is.

    Anyway, I came up with:

    location = [t[1] for t in headers if t[0] == 'location'][0]

    which works, but is getting on towards the cryptic end of things. Is
    there a better idiom for this?
     
    Roy Smith, Sep 5, 2010
    #1
    1. Advertising

  2. On Sunday 05 September 2010, it occurred to Roy Smith to exclaim:
    > I'm using httplib, and want to get the Location header from the
    > response. The getheaders() method gives you back a list of (name,
    > value) tuples. It would be a lot more convenient if it gave you back a
    > dict, but it is what it is.


    It may not be a dict, but you can always make it one:

    >>> L = [('a',1), ('b', 42), ('c', 0)]
    >>> dict(L)

    {'a': 1, 'c': 0, 'b': 42}
    >>>
     
    Thomas Jollans, Sep 5, 2010
    #2
    1. Advertising

  3. On Sep 5, 2010, at 1:09 PM, Roy Smith wrote:

    > I'm using httplib, and want to get the Location header from the
    > response. The getheaders() method gives you back a list of (name,
    > value) tuples. It would be a lot more convenient if it gave you
    > back a
    > dict, but it is what it is.
    >
    > Anyway, I came up with:
    >
    > location = [t[1] for t in headers if t[0] == 'location'][0]
    >
    > which works, but is getting on towards the cryptic end of things. Is
    > there a better idiom for this?


    Are you concerned about efficiency? If it's not important, being less
    terse would make it less cryptic:
    location = None
    for name, value in headers:
    if name == "location":
    location = value
    break

    If you prefer terse, IMHO this is less cryptic (but untested):

    location = [value for name, value in headers if name == 'location']
    [0]


    Be careful if you decide to turn the list of tuples into a dictionary.
    HTTP headers can repeat and straightforward code to turn the (name,
    value) pairs into a dict could end up overwriting data.

    Cheers
    P
     
    Philip Semanchuk, Sep 5, 2010
    #3
  4. Roy Smith

    Peter Otten Guest

    Philip Semanchuk wrote:

    >
    > On Sep 5, 2010, at 1:09 PM, Roy Smith wrote:
    >
    >> I'm using httplib, and want to get the Location header from the
    >> response. The getheaders() method gives you back a list of (name,
    >> value) tuples. It would be a lot more convenient if it gave you
    >> back a
    >> dict, but it is what it is.
    >>
    >> Anyway, I came up with:
    >>
    >> location = [t[1] for t in headers if t[0] == 'location'][0]
    >>
    >> which works, but is getting on towards the cryptic end of things. Is
    >> there a better idiom for this?

    >
    > Are you concerned about efficiency? If it's not important, being less
    > terse would make it less cryptic:
    > location = None
    > for name, value in headers:
    > if name == "location":
    > location = value
    > break


    This is actually more efficient because unlike Roy's (and your other
    solution) it doesn't build a list, and it doesn't waste cycles in the loop
    once the location is found. You can write it as a generator expression like
    so:

    location = next((value for name, value in headers if name == "location"),
    None)

    But just converting the headers to a dict is clearer and probably even
    faster because it moves the loop from Python to C.

    > If you prefer terse, IMHO this is less cryptic (but untested):
    >
    > location = [value for name, value in headers if name == 'location']
    > [0]
    >
    >
    > Be careful if you decide to turn the list of tuples into a dictionary.
    > HTTP headers can repeat and straightforward code to turn the (name,
    > value) pairs into a dict could end up overwriting data.
     
    Peter Otten, Sep 5, 2010
    #4
  5. On Sep 5, 2010, at 1:45 PM, Peter Otten wrote:

    > Philip Semanchuk wrote:
    >
    >>
    >> On Sep 5, 2010, at 1:09 PM, Roy Smith wrote:
    >>
    >>> I'm using httplib, and want to get the Location header from the
    >>> response. The getheaders() method gives you back a list of (name,
    >>> value) tuples. It would be a lot more convenient if it gave you
    >>> back a
    >>> dict, but it is what it is.
    >>>
    >>> Anyway, I came up with:
    >>>
    >>> location = [t[1] for t in headers if t[0] == 'location'][0]
    >>>
    >>> which works, but is getting on towards the cryptic end of things.
    >>> Is
    >>> there a better idiom for this?

    >>
    >> Are you concerned about efficiency? If it's not important, being less
    >> terse would make it less cryptic:
    >> location = None
    >> for name, value in headers:
    >> if name == "location":
    >> location = value
    >> break

    >
    > This is actually more efficient because unlike Roy's (and your other
    > solution) it doesn't build a list, and it doesn't waste cycles in
    > the loop
    > once the location is found.


    Upon further reflection, though, I realize that my solution is not
    equivalent to the original. In the case of duplicated headers, the
    original would return the last value of the location header, my code
    would return the first. For the HTTP Location header this is only a
    theoretical problem because the HTTP spec doesn't provide for sending
    more than one.

    However if this code were made into a function for retrieving the
    value of an arbitrary header (as seems likely), one would have to
    decide how to handle repeating headers. Neither my code nor the
    original handle that possibility. Nor does a naive conversion into a
    dict, as I mentioned before.

    Cheers
    P

    > You can write it as a generator expression like
    > so:
    >
    > location = next((value for name, value in headers if name ==
    > "location"),
    > None)
    >
    > But just converting the headers to a dict is clearer and probably even
    > faster because it moves the loop from Python to C.
    >
    >> If you prefer terse, IMHO this is less cryptic (but untested):
    >>
    >> location = [value for name, value in headers if name ==
    >> 'location']
    >> [0]
    >>
    >>
    >> Be careful if you decide to turn the list of tuples into a
    >> dictionary.
    >> HTTP headers can repeat and straightforward code to turn the (name,
    >> value) pairs into a dict could end up overwriting data.

    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
     
    Philip Semanchuk, Sep 5, 2010
    #5
    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:
    578
    Thomas J. Gritzan
    Oct 6, 2006
  2. tuples within tuples

    , Oct 26, 2007, in forum: Python
    Replies:
    12
    Views:
    616
    Dennis Lee Bieber
    Oct 27, 2007
  3. xera121
    Replies:
    8
    Views:
    760
    lolmc
    Sep 30, 2009
  4. Gnarlodious

    Transform two tuples item by item

    Gnarlodious, Dec 20, 2011, in forum: Python
    Replies:
    3
    Views:
    174
    Gnarlodious
    Dec 20, 2011
  5. Jon Reyes
    Replies:
    18
    Views:
    271
    Mitya Sirenef
    Feb 19, 2013
Loading...

Share This Page