简体   繁体   中英

How to quickly access all values corresponding to a specific second level key regardless of first level key in a Python dictionary?

I have a Python Dictionary like:

Mydict = {'a': {'y': 1, 'x': 5}, 'b': {'y': 10, 'x': 8}}

Is there any quick way to access the values corresponding to the key: 'x', which in this case is a second level key, regardless of the first level key?

I know it can be done using a for loop like:

mylist=[]
for k in Mydict.keys():
    mylist.append(Mydict[k]['x'])

But is there any quick one line method for it?

Using list-comprehension :

mylist = [v['x'] for v in Mydict.values()]

Since you do not need the outer keys, you just iterate over the inner dicts, and get the desired 'x' value.

Note: This will only work if each inner dict has an 'x' key, to be sure, and to minimize errors, you can do this:

mylist = [v.get('x', None) for v in Mydict.values()]

This will function the same, only if there is no 'x' key in the dictionary, it will return None instead of a KeyError exception.

For timing, and to see which method is best, look at the answer by Thorsten Kranz

For completeness: map is usually a good alternative to list comprehension, eg

mylist = map(lambda v: v['x'], Mydict.values())

or

mylist = map(lambda k: Mydict[k]['x'], Mydict)

It's usually up to you what you prefer.

EDIT:

As performance came up, here a quick comparison for 1,000,000 repetitions:

import timeit

Mydict = {'a': {'y': 1, 'x': 5}, 'b': {'y': 10, 'x': 8}}

def list_append(d):
    mylist=[]
    for k in d.keys():
        mylist.append(d[k]['x'])

def list_comprehension_values(d):
    return [v['x'] for v in d.values()]

def list_comprehension_keys(d):
    return [d[k]['x'] for k in d]

def map_values(d):
    return map(lambda v: v['x'], d.values())

def map_keys(d):    
    return map(lambda k: d[k]['x'], d)

for method_name in ["list_append",
                    "list_comprehension_values",
                    "list_comprehension_keys",
                    "map_values",
                    "map_keys"]:
    t = timeit.timeit(method_name + "(Mydict)",
                      "from __main__ import Mydict, " + method_name, 
                      number=1000000)
    print "%s: %.2f seconds" % (method_name, t)

results in:

list_append: 0.95 seconds
list_comprehension_values: 0.56 seconds
list_comprehension_keys: 0.47 seconds
map_values: 1.02 seconds
map_keys: 1.01 seconds

* Edit 2 *

For a larger dictionary

Mydict = dict(zip(range(10000), 
              [{'x' : random.randint(0,10), 'y' : random.randint(0,10)} 
                  for i in range(10000)]))

and less repetitions (number=10000), the values are different:

list_append: 16.41 seconds
list_comprehension_values: 6.00 seconds
list_comprehension_keys: 9.62 seconds
map_values: 15.23 seconds
map_keys: 18.42 seconds

So saving on the key-lookup is better here.

列表理解将是一行,几乎快了一倍:

mylist = [mydict[k]['x'] for k in mydict]

Use a list comprehension

mylist = [Mydict[k]['x'] for k in Mydict]

Note that iterating over Mydict automatically iterates over the keys, so no need to iterate over Mydict.keys() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM