Pythonic方式从字典中访问任意元素

时间:2012-05-15 03:05:07

标签: python

我有一本字典,里面装满了物品。我想偷看一个单一的,任意的项目:

print "Amongst our dictionary's items are such diverse elements as: %s" % arb(dictionary)

我不关心哪个项目。它不需要随机

我可以想出很多实现这一点的方法,但它们看起来都很浪费。我想知道在Python中是否有任何首选习语,或者(如果我错过了一个,那就更好)。

def arb(dictionary):
# Creates an entire list in memory. Could take a while.
    return list(dictionary.values())[0]

def arb(dictionary):
# Creates an entire interator. An improvement.
    for item in dictionary.itervalues():
        return item

def arb(dictionary):
# No iterator, but writes to the dictionary! Twice!
    key, value = dictionary.popitem()
    dictionary[key] = value
    return value

我处在一个性能不够严重的位置,这很重要(还),所以我可以被指责过早优化,但我正在努力改进我的Python编码风格,所以如果有一个很容易理解变体,采用它会很好。

4 个答案:

答案 0 :(得分:28)

与您的第二个解决方案类似,但在我看来更为明显:

return next(iter(dictionary.values()))

这适用于python 2以及python 3,但在python 2中,这样做效率更高:

return next(dictionary.itervalues())

答案 1 :(得分:10)

避免整个values / itervalues / viewvalues混乱,这在Python2或Python3中同样有效

dictionary[next(iter(dictionary))]

或者如果您更喜欢生成器表达式

next(dictionary[x] for x in dictionary)

答案 2 :(得分:2)

我认为这个问题得到了很好的回答,但希望这种比较能够清楚地说明干净的代码与时间的关系:

from timeit import timeit
from random import choice
A = {x:[y for y in range(100)] for x in range(1000)}
def test_pop():
    k, v= A.popitem()
    A[k] = v

def test_iter(): k = next(A.iterkeys())

def test_list(): k = choice(A.keys())

def test_insert(): A[0] = 0

if __name__ == '__main__':
    print('pop', timeit("test_pop()", setup="from __main__ import test_pop", number=10000))
    print('iter', timeit("test_iter()", setup="from __main__ import test_iter", number=10000))
    print('list', timeit("test_list()", setup="from __main__ import test_list", number=10000))
    print('insert', timeit("test_insert()", setup="from __main__ import test_insert", number=10000))

结果如下:

('pop', 0.0021750926971435547)
('iter', 0.002003908157348633)
('list', 0.047267913818359375)
('insert', 0.0010859966278076172)

似乎使用iterkeys只是边缘更快,然后弹出一个项目并重新插入,但比创建列表并从中选择一个随机对象快10倍。

答案 3 :(得分:0)

为什么不使用random

import random

def arb(dictionary):
    return random.choice(dictionary.values())

这清楚地表明结果纯粹是任意的,而不是实现的副作用。在性能成为一个实际问题之前,总是要明确速度。

令人遗憾的是dict_values不支持索引,能够传入值视图会很高兴。

更新:由于每个人都如此着迷于性能,上述功能需要<120ms才能从100万项的字典中返回一个随机值。依靠清晰的代码并不是令人惊讶的性能,而是它的成功。