1

对于我正在处理的一个项目,我正在处理许多深度嵌套的 dict-and-list 数据结构。我经常发现自己在进行查找,希望返回一个包含单个成员的列表。查找可能完全失败,或者只是返回零结果,所以我可以编写如下代码:

try:
    value_I_need = lookup_results[0]
except IndexError:
    # handle lookup failure, keep going

但最近我一直想知道编写一个循环是否更具前瞻性,最初假设它只发生零次或一次:

value_I_need = None
for value_I_need in lookup_results:
    break
if value_I_need is None:
    # handle lookup failure, keep going

(我说“面向未来”是因为我可能想重写或概括此代码以处理具有多个结果的查找。)这两种方法中的任何一种是否存在固有的非pythonic、错误或速度慢?

4

3 回答 3

5

内置函数next()正是这样做的:

a = ()
b = [1, 2, 3]
print next(iter(a), "empty") # prints "empty", as a doesn't give any values.
print next(iter(b), "empty") # prints 1, the 1st value of b
于 2012-05-30T23:07:03.123 回答
0

为什么for?可以更清楚地说:

if value_I_need not in lookup_results:
    print "I need it but it ain't there"

换句话说,你不会得到一个序列

for x in y:
    break

ify是序列类型,x将是第一个元素;对于 dict 类型,它将是第一个元素的(随机)键。x之前注定的,以后for就不会了。那是:

x = 5
for x in range(10):
     break

将 0 绑定到x,并且它在第一行中的任何五位都对第二行没有影响。

于 2012-05-30T23:00:30.917 回答
0

保持简单明了。

if len(lookup_results) == 1:
    result = lookup_results[0]
    # ...
else:
    # ...

这里的任何性能差异 - 正面或负面 - 都将是微观的,它更清楚地传达了您的意图。

如果您以后需要重构,那么编写这些方式中的任何一种都不会对您花费的时间产生重大影响(当然,除非您不知道代码在做什么)。

于 2012-05-30T23:09:26.913 回答