Extracting item from list of tuples?

Philip Semanchuk philip at semanchuk.com
Sun Sep 5 14:30:52 EDT 2010


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




More information about the Python-list mailing list