在2元组序列中测试与第一项元组匹配的最Pythonic方法是什么?

Gho*_*r21 4 python

假设你有一系列2元组:

seq_of_tups = (('a', 1), ('b', 2), ('c', 3))
Run Code Online (Sandbox Code Playgroud)

并且您想测试if 'a'是序列中任何元组的第一项.

什么是最恐怖的方式?

转换为字典并测试密钥,这似乎很容易理解?即

'a' in dict(seq_of_tups)
Run Code Online (Sandbox Code Playgroud)

使用可爱的拉链技巧,除非你知道这个技巧,否则不是特别清楚?即

'a' in zip(*seq_of_tups)[0]
Run Code Online (Sandbox Code Playgroud)

或者真的明确地图?即

'a' in map(lambda tup: tup[0], seq_of_tups)
Run Code Online (Sandbox Code Playgroud)

还是有比这些选择更好的方法?

jam*_*lak 11

>>> seq_of_tups = (('a', 1), ('b', 2), ('c', 3))
>>> any(x == 'a' for x, y in seq_of_tups)
True
Run Code Online (Sandbox Code Playgroud)

对于任何大小的元组,您可以使用它:

any(x[0] == 'a' for x in seq_of_tups)
Run Code Online (Sandbox Code Playgroud)

这里还有一些有趣的时间:

>python -m timeit -s "seq_of_tups = (('a', 1), ('b', 2), ('c', 3))" 
                 "any(x == 'a' for x, y in seq_of_tups)"
1000000 loops, best of 3: 0.564 usec per loop

>python -m timeit -s "seq_of_tups = (('a', 1), ('b', 2), ('c', 3))" 
                 "'a' in (x[0] for x in seq_of_tups)"
1000000 loops, best of 3: 0.526 usec per loop

>python -m timeit -s "seq_of_tups = (('a', 1), ('b', 2), ('c', 3)); 
                      from operator import itemgetter; from itertools import imap" 
                 "'a' in imap(itemgetter(0), seq_of_tups)"
1000000 loops, best of 3: 0.343 usec per loop
Run Code Online (Sandbox Code Playgroud)

  • 这是避免遍历整个列表的好方法(平均当然). (3认同)

Ash*_*ary 5

>>> tups = (('a', 1), ('b', 2), ('c', 3))

>>> 'a' in (x[0] for x in tups)
True
>>> 'd' in (x[0] for x in tups)
False
Run Code Online (Sandbox Code Playgroud)

上述解决方案将a在找到后立即退出,证明:

>>> tups = (('a', 1),('a',5), ('b', 2), ('c', 3))
>>> gen=(x[0] for x in tups)
>>> 'a' in gen
True
>>> list(gen)
['a', 'b', 'c']  #this result means generator stopped at first 'a'
Run Code Online (Sandbox Code Playgroud)

  • 显然Python非常聪明,不能首先将生成器转换为列表(在itertools.repeat(5)`中使用`5进行测试).它与jamylak的解决方案同样有效. (3认同)