有没有一种方法可以在Python中不使用for循环来查找元组中的项目?

发布于 2024-12-20 00:55:39 字数 296 浏览 0 评论 0原文

我有一组 Control 值,我想找到具有匹配名称的值。现在我用这个:

listView
for control in controls:
    if control.name == "ListView":
        listView = control

我可以做得比这更简单吗?也许是这样的:

listView = controls.FirstOrDefault(c => c.name == "ListView")

I have a tuple of Control values and I want to find the one with a matching name. Right now I use this:

listView
for control in controls:
    if control.name == "ListView":
        listView = control

Can I do it simpler than this? Perhaps something like:

listView = controls.FirstOrDefault(c => c.name == "ListView")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

向日葵 2024-12-27 00:55:39

这里有一个选项:

listView = next(c for c in controls if c.name == "ListView")

请注意,如果不存在匹配项,这将引发 StopIteration ,因此您需要将其放入 try/ except 中,并在获得 时将其替换为默认值停止迭代。

或者,您可以将默认值添加到可迭代对象中,以便 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()

Here is one option:

listView = next(c for c in controls if c.name == "ListView")

Note that this will raise a StopIteration if no matching item exists, so you will need to put this in a try/except and replace it with a default if you get a StopIteration.

Alternatively you can add your default value to the iterable so the next call always succeeds.

from itertools import chain
listView = next(chain((c for c in controls if c.name == "ListView"), [default])

If you are using Python 2.5 or lower change the call from next(iterable) to iterable.next().

一笑百媚生 2024-12-27 00:55:39

出于纯粹的好奇,我将自己的答案与您的原始代码和FJ的解决方案结合起来,进行性能对比测试。

看来您的解决方案是所有解决方案中最快的。我的解决方案检查控件元组的所有可能元素,因此随着元组大小的增加,它会变慢。

这是代码:

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! :)

Out of sheer curiosity, I integrated my own answer with your original code and F.J.'s solutions to make a comparative performance test.

It seems that your solution is the fastest of them all. My solution check all possible elements of the controls tuple, so it will be slower as the size of the tuple increases.

Here is the code:

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)    

and here is the output on my system:

[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! :)

一瞬间的火花 2024-12-27 00:55:39
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))
listView = filter(lambda c: c.name=="ListView", controls)[0]

Throws IndexError if no such control exists.

A bit esoteric, but without requiring try/except:

listView = (lambda x: x[0] if x else None)(filter(lambda c: c.name=="ListView", controls))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文