views:

163

answers:

6
[{'id':44}, {'name':'alexa'},{'color':'blue'}]

I want to select whatever in the list that is "id". Basically, I want to print 44, since that's "id" in the list.

+3  A: 

You could do something like this:

>>> KEY = 'id'
>>>
>>> my_list = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
>>> my_ids = [x[KEY] for x in my_list if KEY in x]
>>> print my_ids
[44]

Which is obviously a list of the values you want. You can then print them as required.

DisplacedAussie
+5  A: 

That's a weird data structure... A list of one item dictionaries.

key = 'id'
l = [{'id':44}, {'name':'alexa'},{'color':'blue'}]

print [ x[key] for x in l if key in x ][0]

Assuming you can rely on key being present precisely once...

Maybe you should just convert the list into a dictionary first:

key = 'id'
l = [{'id':44}, {'name':'alexa'},{'color':'blue'}]

d = {}
for x in l:
    d.update(x)
print d[key]
Douglas Leeder
`.has_key` wtf? why is this being even upvoted?
SilentGhost
Perhaps because it answers the question? has_key http://docs.python.org/library/stdtypes.html#dict.has_keyDeprecated, but still works...
Douglas Leeder
has been deprecated for 4.5 years, and of course it doesn't even exist in py3k. So, I don't think that it'd qualify as *still works*.
SilentGhost
I wonder why `has_key` doesn't trigger a deprecation warning in 2.6 :(
gnibbler
@SilentGhost I've changed it anyway - `in` is twice as fast...
Douglas Leeder
+2  A: 
 >>> from itertools import dropwhile
 >>> def find_value(l, key):
 ...    return dropwhile(lambda x: key not in x, l).next()[key]
 >>> find_value([{'id':44}, {'name':'alexa'},{'color':'blue'}], "id")

This will do a linear search, but only until the element is found.

If you want to have proper error handling, use:

def find_value(l, key):
    try:
        return dropwhile(lambda x: key not in x, l).next()[key]
    except StopIteration:
        raise ValueError(key)
Torsten Marek
Instead of using generator.next(), you can use next(generator,def_val). The latter method will return a def_val when StopIteration is reached, so you don't need to wrap it up in a try\catch block.
HS
But then you'd have to check the default value, since not finding the element is exception---unless the function should be extended to include a default value, too. Good suggestion, though.
Torsten Marek
+4  A: 

All the other answers solve your problem, I am just suggesting an alternative way of going about doing this.

Instead of having a list of dicts where you query on the key and have to iterate over all list items to get values, just use a dict of lists. Each key would map to a list of values (or just one value if all your dicts had distinct sets of keys).

So,

data=[{'id':44}, {'name':'alexa'},{'color':'blue'}]

becomes

data={'id':[44], 'name':['alexa'], 'color':['blue']}

and you can neatly access the value for 'id' using data['id'] (or data['id'][0] if you only need one value).

If all your keys are distinct across the dicts (as in your example) you don't even have to have lists of values.

data={'id':44, 'name':'alexa', 'color':'blue'}

Not only does this make your code cleaner, it also speeds up your queries which no longer have to iterate over a list.

MAK
+3  A: 

Probably this is the best solution:

>>> L = [{'id':44}, {'name':'alexa'},{'color':'blue'}]

>>> newd = {}
>>> for d in L:
...    newd.update(d)
>>> newd['id']
44
Lennart Regebro
Or `newd = dict(tuple(d.items()) for d in L)`
Chris Lutz
A: 
>>> L = [{'id':44}, {'name':'alexa'},{'color':'blue'}]
>>> newd=dict(d.items()[0] for d in L)
>>> newd['id']
44
gnibbler