简体   繁体   English

Python:list comprehensions vs. lambda

[英]Python: list comprehensions vs. lambda

I want to retrieve the integer value from the sublist containing "b" as the first element (b will only appear once in the list) 我想从包含“b”的子列表中检索整数值作为第一个元素(b只会在列表中出现一次)

Those two ways came to my mind: 我想到了这两种方式:

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]

They both work. 他们都工作。 Is any of the two preferable (regarding runtime), is there an even better third way? 是两个中的任何一个(关于运行时),是否有更好的第三种方式?

When the list is so small there is no significant difference between the two. 当列表如此之小时,两者之间没有显着差异。 If the input list can grow large then there is a worse problem: you're iterating over the whole list, while you could stop at the first element. 如果输入列表变大,则会出现更糟糕的问题:您在整个列表上进行迭代,而您可以在第一个元素处停止。 You could accomplish this with a for loop, but if you want to use a comprehension-like statement, here come generator expressions : 您可以使用for循环来完成此操作,但是如果您想使用类似于类似理解的语句,那么这里有生成器表达式

# like list comprehensions but with () instead of []
gen = (b for a, b in foo if a == 'b')
my_element = next(gen)

or simply: 或者干脆:

my_element = next(b for a, b in foo if a == 'b')

If you want to learn more about generator expressions give a look at PEP 289 . 如果您想了解有关生成器表达式的更多信息,请参阅PEP 289


Note that even with generators and iterators you have more than one choice. 请注意,即使使用生成器和迭代器,您也有多个选择。

# 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))

I personally don't like and don't recommend this because it is much less readable. 我个人不喜欢也不推荐这个,因为它的可读性低得多。 It turns out that this is actually slower than my first snippet, but more in general using filter() instead of a generator expression might be faster in some special cases. 事实证明,这实际上比我的第一个片段慢,但在一些特殊情况下,通常使用filter()而不是生成器表达式可能会更快。

In any case if you need benchmarking your code, I recommend using the timeit module . 在任何情况下,如果您需要对代码进行基准测试,我建议您使用timeit模块

This is slower than DavidE's answer (I timed it), but has the advantage of simplicity: 这比DavidE的答案慢(我定时),但具有简单的优点:

z = dict(foo)['b']

Of course it assumes that your keys are all hashable, but that's fine if they are strings. 当然它假设您的密钥都是可以清洗的,但如果它们是字符串就没问题。 If you need to do multiple lookups though this is definitely the way to go (just be sure to only convert to a dict once). 如果你需要做多次查找,虽然这绝对是要走的路(只需确保只转换为一次dict)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM