Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.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
从字典中访问任意元素的Pythonic方法_Python - Fatal编程技术网

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

从字典中访问任意元素的Pythonic方法,python,Python,我有一本字典,里面有很多东西。我想看看一个单独的任意项目: print("Amongst our dictionary's items are such diverse elements as: %s" % arb(dictionary)) 我不在乎哪一项。它不需要是随机的 我可以想出很多方法来实现这一点,但它们似乎都是浪费。我想知道Python中是否有首选的习惯用法,或者(甚至更好)我是否缺少一种 def arb(dictionary): # Creates an ent

我有一本字典,里面有很多东西。我想看看一个单独的任意项目:

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 iterator. An improvement.
    for item in dictionary.values():
        return item

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

我现在的处境是,性能还不够关键,因此我可能会被指责为过早优化,但我正在努力改进我的Python编码风格,因此如果有一个易于理解的变体,最好采用它。

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

return next(iter(dictionary.values()))
这在Python2和Python3中都适用,但在Python2中,这样做更有效:

return next(dictionary.itervalues())

为什么不使用
random

import random

def arb(dictionary):
    return random.choice(dictionary.values())
这非常清楚地表明,结果完全是任意的,而不是实现的副作用。在性能成为实际问题之前,始终保持清晰而不是速度

很遗憾,dict_值不支持索引,最好能在值视图中传递


更新:由于每个人都如此痴迷于性能,因此上述函数需要避免整个
/
itervalues
/
视图值
混乱,这在Python2或Python3中同样有效

dictionary[next(iter(dictionary))]
或者,如果您更喜欢生成器表达式

next(dictionary[x] for x in dictionary)

我相信这个问题已经得到了很好的回答,但希望这个比较能够揭示干净代码与时间之间的权衡:

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倍。

关于
dictionary.itervalues().next()
?这至少比你的第二个
arb
函数要好。@sgerg我本来打算提交的,但你可以继续DDo他们需要在通话中使用不同的项目吗?所有这些都将返回相同的项目…当您知道不需要做额外的工作时,不做额外的工作并不是过早的优化。这是一种效率。如果你想偷看一个项目(相对于一个值),你应该使用
iteritems
而不是
itervalues
/nitpick/应该注意,如果dict是空的,这会引发StopIteration。但是如果你想避免
StopIteration
,你可以指定一个默认值,例如
next(dictionary.itervalues(),无)
。我不确定我是否认为它“明显得多”,但在一个表达式中有明确的适合点。@奇怪的想法:如果你只是想从迭代器中得到一个元素,
下一步
。b中a的
没有意义:返回c
或者在循环的第一次迭代中有一个无条件的
break
语句。我已经对现代python的答案更新了3次,因为这仍然是一个流行的问题。如果您对我所做的更改不满意,请随意回滚或编辑以满足您的需要。如果已指定所选元素不需要是随机的,则这是浪费时间。一个docstring(和名称!)对于这样的观察来说是完全足够的。如果名称是“任意”的,并且操作是遍历键,那么我就不清楚这个名称,所以是的,docstring是必要的。如果你必须写一个docstring来解释为什么你的代码没有表现出来,也许答案是写更清晰的代码。对于这样的操作,120毫秒是完全不能接受的。这将在不到一微秒的时间内完成。你把它放在以前使用的
d[next(iter(d))]
中,你的应用程序可能会慢一百万倍。你也可以简单地执行
next(iter(dictionary.values())
@Ev.Kounis,但在python2中,这会创建一个额外的列表。
map
也会在python2中创建一个列表。@user2357112,啊,是的,你是对的。我将删除这个,因为有些人仍然试图支持2和3