我有Control
个值的元组,我想找到一个名称匹配的元组。现在我用这个:
listView
for control in controls:
if control.name == "ListView":
listView = control
我可以比这简单吗?也许是这样的事情:
listView = controls.FirstOrDefault(c => c.name == "ListView")
答案 0 :(得分:6)
这是一个选项:
listView = next(c for c in controls if c.name == "ListView")
请注意,如果不存在匹配项,则会引发StopIteration
,因此您需要将其设置为try / except,如果获得StopIteration
,则将其替换为默认值。
或者,您可以将默认值添加到iterable中,以便next
调用始终成功。
from itertools import chain
listView = next(chain((c for c in controls if c.name == "ListView"), [default])
如果您使用的是Python 2.5或更低版本,请将呼叫从next(iterable)
更改为iterable.next()
。
答案 1 :(得分:2)
出于纯粹的好奇心,我将自己的答案与原始代码和F.J.的解决方案相结合,进行了比较性能测试。
您的解决方案似乎是最快的解决方案。我的解决方案检查控件元组的所有可能元素,因此随着元组大小的增加它会变慢。
以下是代码:
from timeit import Timer as T
from itertools import chain, dropwhile
class control(object):
def __init__(self, name):
self.name = name
def johan_venge(tuple_):
for el in tuple_:
if el.name == 'foobar':
return el
return None
def mac(tuple_):
return filter(lambda x : x.name == 'foobar', tuple_)[0]
def mac2(tuple_):
return list(dropwhile(lambda x : x.name != 'foobar', tuple_))[0]
def fj(tuple_):
return next(c for c in tuple_ if c.name == 'foobar')
def fj2(tuple_):
return next(chain((c for c in tuple_ if c.name == 'foobar')))
if __name__ == '__main__':
REPS = 10000
controls = (control('hello'), control('world'), control('foobar'))
print T(lambda : johan_venge(controls)).repeat(number = REPS)
print T(lambda : mac(controls)).repeat(number = REPS)
print T(lambda : mac2(controls)).repeat(number = REPS)
print T(lambda : fj(controls)).repeat(number = REPS)
print T(lambda : fj2(controls)).repeat(number = REPS)
这是我系统上的输出:
[0.005961179733276367, 0.005975961685180664, 0.005918025970458984]
[0.013427019119262695, 0.013586044311523438, 0.013450145721435547]
[0.024325847625732422, 0.0254058837890625, 0.02396702766418457]
[0.014491081237792969, 0.01442408561706543, 0.01484990119934082]
[0.01691603660583496, 0.016616106033325195, 0.016437053680419922]
HTH! :)
答案 2 :(得分:1)
listView = filter(lambda c: c.name=="ListView", controls)[0]
如果不存在此类控件,则抛出 IndexError 。
有点深奥,但不需要尝试/除了:
listView = (lambda x: x[0] if x else None)(filter(lambda c: c.name=="ListView", controls))