用于查询 Python 列表中哪个元素最先出现的语法糖

发布于 2024-12-20 02:17:00 字数 183 浏览 0 评论 0原文

我有一个包含许多元素的列表。

我关心它的两个元素,ab

我不知道列表的顺序,也不想对其进行排序。

是否有一个很好的单行代码,如果 a 出现在 b 之前,则返回 True,否则返回 false?

I have a list of many elements.

I care about two of its elements, a and b.

I don't know the order of the list, nor do I want to sort it.

Is there a nice one-liner that will return True if a occurs before b and false otherwise?

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

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

发布评论

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

评论(4

追星践月 2024-12-27 02:17:00

为了多样性,您还可以:

b in l[l.index(a):]

如果 a == b,则为 True。如果您知道a != b

b in l[l.index(a) + 1:]

In the interests of diversity, you could also:

b in l[l.index(a):]

This will be True if a == b. If you know that a != b,

b in l[l.index(a) + 1:]
诗笺 2024-12-27 02:17:00

编辑:重写以检查更多情况,

好,所以这个问题需要更多的工作。马克·拜尔斯 (Mark Byers) 是完全正确的,因为我的第一个测试仅涵盖结果为 True 的情况。这尤其重要,因为我们需要其他解决方案的异常处理程序。因此,我更详细地介绍了:

stmts = {
"Mark Byers: ": "x = l.index(a) < l.index(b)",
"jcollado: ": """try:
    x = bool(l.index(b, l.index(a)))
except ValueError:
    x = False""",
"Greg Hewgill: ": """try:
   x = b in l[l.index(a):]
except ValueError:
   x = False"""
}

setups = ["a = 80; b = 90; l = list(range(100))", 
          "a = 5; b = 10; l = list(range(100))", 
          "a = 90; b = 80; l = list(range(100))",
          "a = 10; b = 5; l = list(range(100))"]

import timeit
for se in setups:
    print(se)
    for st in stmts:
        print(st, timeit.timeit(stmt=stmts[st], setup=se))
    print()

结果:

a = 80; b = 90; l = list(range(100))
Mark Byers:  5.760545506106019
Greg Hewgill:  3.454101240451526     # Tie!
jcollado:  3.4574156981854536        # Tie!


a = 5; b = 10; l = list(range(100))
Mark Byers:  1.0853995762934794      # Close runner-up!
Greg Hewgill:  1.7265326426395209
jcollado:  1.0528704983320782        # Winner!

a = 90; b = 80; l = list(range(100))
Mark Byers:  5.741535600372806
Greg Hewgill:  3.623253643486848     # Winner!
jcollado:  4.567104188774817

a = 10; b = 5; l = list(range(100))
Mark Byers:  1.0592141197866987      # Winner!
Greg Hewgill:  4.73399648151641
jcollado:  4.77415749512712

因此,jcollado 方法的效率增益大部分被异常处理程序的成本所消耗(特别是如果它触发)。所有三种解决方案都有一半的时间获胜(或与获胜者并列),因此很难说哪种方法最适合您的实际数据。也许您可能想要选择最容易阅读的一本。

Edit: Rewritten to check more cases

OK, so this problem needs a bit more work. Mark Byers is completely right in that my first test only covered cases where the result would be True. This is especially relevant because we need exception handlers for the other solutions. So I've gone into a bit more detail:

stmts = {
"Mark Byers: ": "x = l.index(a) < l.index(b)",
"jcollado: ": """try:
    x = bool(l.index(b, l.index(a)))
except ValueError:
    x = False""",
"Greg Hewgill: ": """try:
   x = b in l[l.index(a):]
except ValueError:
   x = False"""
}

setups = ["a = 80; b = 90; l = list(range(100))", 
          "a = 5; b = 10; l = list(range(100))", 
          "a = 90; b = 80; l = list(range(100))",
          "a = 10; b = 5; l = list(range(100))"]

import timeit
for se in setups:
    print(se)
    for st in stmts:
        print(st, timeit.timeit(stmt=stmts[st], setup=se))
    print()

results in:

a = 80; b = 90; l = list(range(100))
Mark Byers:  5.760545506106019
Greg Hewgill:  3.454101240451526     # Tie!
jcollado:  3.4574156981854536        # Tie!


a = 5; b = 10; l = list(range(100))
Mark Byers:  1.0853995762934794      # Close runner-up!
Greg Hewgill:  1.7265326426395209
jcollado:  1.0528704983320782        # Winner!

a = 90; b = 80; l = list(range(100))
Mark Byers:  5.741535600372806
Greg Hewgill:  3.623253643486848     # Winner!
jcollado:  4.567104188774817

a = 10; b = 5; l = list(range(100))
Mark Byers:  1.0592141197866987      # Winner!
Greg Hewgill:  4.73399648151641
jcollado:  4.77415749512712

So the efficiency gain from jcollado's method is mostly eaten up by the cost of the exception handler (expecially if it triggers). All three solutions win (or tie with the winner) half of the time, so which method works best on your actual data is hard to say. Perhaps you might want to go with the one that's easiest to read.

等数载,海棠开 2024-12-27 02:17:00

您可以使用list.index

l.index(a) < l.index(b)

这当然假设这两个项目都存在于列表中。

You can use list.index:

l.index(a) < l.index(b)

This of course assumes that both items are present in the list.

绻影浮沉 2024-12-27 02:17:00

Mark Byers 的响应效果很好,但如果列表很长并且两个元素都接近末尾,则效率不会很高。

要仅遍历列表一次,您可以使用以下命令:

l.index(b, l.index(a))

这是所需的单行代码,但无论如何您都需要捕获 ValueError 异常。

Response from Mark Byers works fine, but it won't be very efficient if list is long and both elements are close to the end.

To traverse the list just once, you can use this:

l.index(b, l.index(a))

This is a one-liner as required, but you'll need to capture ValueError exception anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文