Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何快速访问与Python字典中特定的第二级键对应的所有值,而不考虑第一级键?_Python_Dictionary - Fatal编程技术网

如何快速访问与Python字典中特定的第二级键对应的所有值,而不考虑第一级键?

如何快速访问与Python字典中特定的第二级键对应的所有值,而不考虑第一级键?,python,dictionary,Python,Dictionary,我有一本Python字典,比如: Mydict={'a':{'y':1,'x':5},'b':{'y':10,'x':8} 是否有任何快速方法可以访问与键“x”对应的值,在本例中,该键是第二级键,而与第一级键无关 我知道可以使用for循环完成,如: mylist=[] for k in Mydict.keys(): mylist.append(Mydict[k]['x']) 但是有没有快速的一行方法呢?一个列表理解应该是一行,速度几乎是两倍: mylist = [mydict[k]['

我有一本Python字典,比如:

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

是否有任何快速方法可以访问与键“x”对应的值,在本例中,该键是第二级键,而与第一级键无关

我知道可以使用for循环完成,如:

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

但是有没有快速的一行方法呢?

一个列表理解应该是一行,速度几乎是两倍:

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

使用列表理解

mylist = [Mydict[k]['x'] for k in Mydict]
请注意,在Mydict上迭代会自动在键上迭代,因此无需在Mydict.keys上迭代。

使用:

因为不需要外部键,所以只需迭代内部dict,就可以得到所需的“x”值

注意:这仅在每个内部dict都有一个“x”键的情况下才起作用,当然,为了尽量减少错误,您可以执行以下操作:

mylist = [v.get('x', None) for v in Mydict.values()]
只有当字典中没有“x”键时,它才会返回None,而不是KeyError异常

为了确定时间,并确定哪种方法最好,请查看答案的完整性:map通常是列表理解的一个很好的替代方法,例如

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

你喜欢什么通常由你决定

编辑:

随着性能的提高,这里是1000000次重复的快速比较:

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)
结果:

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
*编辑2*

为了更大的字典

Mydict = dict(zip(range(10000), 
              [{'x' : random.randint(0,10), 'y' : random.randint(0,10)} 
                  for i in range(10000)]))
如果重复次数较少,则数值不同:

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

因此,在这里保存密钥查找更好。

为什么不更快?现在快一点,请解释一下?我们还是会的。当然,循环开销要小一些。列表理解是以比本机python更有效的方式实现的。而且要快得多,你可以自己检查一下,不要相信我。好吧,我太理论化了。列表理解速度是你的两倍,你使用键的方法比直接访问值还要快——请参见我的答案中的测试。偏好很重要,可读性也很重要,但速度和效率也很重要。当迭代内部指令时,您可以节省查找时间,这比迭代键然后每次查找键要快。另外-在我的回答中,应该使用dict.getkey,default,而不仅仅是访问它。我还感到惊讶的是,直接访问值并不比迭代键并每次查找值快。好吧,为了反驳你的论点,这是在一个非常小的子集上测试的。如果数据集较大,则实现速度可能会有所不同。但我会同意,对于较小的dict,获得键列表,然后查看1或2个值的较小dict可能会更快。。。我希望你明白我的观点,有了数百个外键和内键的dict,跳过外键直接输入会快得多。-即使是较小的数据集,差异也不会像其他人所说的那样快到“两倍”。你是对的,对于较大的词典,你的方法更快。你的方法是提议的选项中最快的。。。。但只适用于小型词典
Mydict = dict(zip(range(10000), 
              [{'x' : random.randint(0,10), 'y' : random.randint(0,10)} 
                  for i in range(10000)]))
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