我想从包含“b”作为第一个元素的子列表中检索整数值(b只会在列表中出现一次)
我想到了这两种方式:
foo = [["a", 5], ["b", 10], ["c", 100]]
y = filter(lambda x: x[0] == "b", foo)
print y[0][1]
z = [foo[i][1] for i in range(len(foo)) if foo[i][0] == "b"]
print z[0]
他们都工作。两个中的任何一个是优选的(关于运行时),还有更好的第三种方式吗?
答案 0 :(得分:10)
当列表如此之小时,两者之间没有显着差异。如果输入列表变大,则会出现更糟糕的问题:您在整个列表上进行迭代,而您可以在第一个元素处停止。您可以使用for循环完成此操作,但是如果您想使用类似于类似理解的语句,那么生成器表达式:
# like list comprehensions but with () instead of []
gen = (b for a, b in foo if a == 'b')
my_element = next(gen)
或简单地说:
my_element = next(b for a, b in foo if a == 'b')
如果您想了解有关生成器表达式的更多信息,请查看PEP 289。
请注意,即使使用生成器和迭代器,您也有多个选择。
# Python 3:
my_element = next(filter(lambda x: x[0] == 'b', foo))
# Python 2:
from itertools import ifilter
my_element = next(ifilter(lambda (x, y): x == 'b', foo))
我个人不喜欢也不推荐这个,因为它的可读性要低得多。事实证明,这实际上比我的第一个片段慢,但在一些特殊情况下,通常使用filter()
代替生成器表达式可能会更快。
在任何情况下,如果您需要对代码进行基准测试,我建议您使用the timeit
module。
答案 1 :(得分:3)
这比DavidE的答案慢(我定时),但具有简单的优点:
z = dict(foo)['b']
当然它假设您的密钥都是可以清洗的,但如果它们是字符串就没问题。 如果你需要进行多次查找,虽然这绝对是一种方法(只需确保只转换为一次dict)。