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

2rs*_*2ts 12 python list syntactic-sugar

我有很多元素的清单.

我关心它的两个元素,ab.

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

是否有一个很好的单线,True如果a之前发生会返回,否则会b错误?

Gre*_*ill 9

为了多样性,您还可以:

b in l[l.index(a):]
Run Code Online (Sandbox Code Playgroud)

这将是True如果a == b.如果你知道a != b,

b in l[l.index(a) + 1:]
Run Code Online (Sandbox Code Playgroud)

  • 如何pythonic!这意味着Java程序员会感到困惑.我喜欢它! (3认同)

Tim*_*ker 8

编辑:重写以检查更多案例

好的,所以这个问题需要更多的工作.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()
Run Code Online (Sandbox Code Playgroud)

结果是:

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
Run Code Online (Sandbox Code Playgroud)

因此,jcollado方法的效率提升主要是由异常处理程序的成本(特别是如果它触发)消耗掉的.所有三种解决方案都有一半的时间赢得(或与获胜者并列),因此很难说哪种方法最适合您的实际数据.也许你可能想要最容易阅读的那个.


Mar*_*ers 7

你可以使用list.index:

l.index(a) < l.index(b)
Run Code Online (Sandbox Code Playgroud)

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


jco*_*ado 5

Mark Byers的回复很好,但是如果列表很长并且两个元素都接近结尾,那么效率不会很高.

要只遍历列表一次,您可以使用:

l.index(b, l.index(a))
Run Code Online (Sandbox Code Playgroud)

这是一个必要的单线程,但ValueError无论如何你都需要捕获异常.