简体   繁体   English

python列表的两个“包含”操作之间的区别

[英]Difference between two “contains” operations for python lists

I'm fairly new to python and have found that I need to query a list about whether it contains a certain item. 我是python的新手,发现我需要查询列表是否包含某个项目。
The majority of the postings I have seen on various websites (including this similar stackoverflow question ) have all suggested something along the lines of 我在各种网站上看到的大多数帖子(包括类似的stackoverflow问题 )都提出了类似的建议

for i in list
    if i == thingIAmLookingFor
        return True

However, I have also found from one lone forum that 但是,我也从一个单独的论坛中找到了

if thingIAmLookingFor in list
    # do work

works. 作品。

I am wondering if the if thing in list method is shorthand for the for i in list method, or if it is implemented differently. 我想知道if thing in list方法中的if thing in list是否为for i in list方法的简写,或者是否以不同方式实现。

I would also like to which, if either, is more preferred. 如果有的话,我也希望哪一个更受欢迎。

In your simple example it is of course better to use in . 在您简单的例子,它当然更好地使用in

However ... in the question you link to , in doesn't work (at least not directly) because the OP does not want to find an object that is equal to something, but an object whose attribute n is equal to something. 但是 ......在你链接到的问题中in 不起作用 (至少不是直接),因为OP不想找到一个等于某个东西的对象,而是一个属性n等于某个东西的对象。

One answer does mention using in on a list comprehension, though I'm not sure why a generator expression wasn't used instead: 一个答案 确实使用何况in一个列表理解,虽然我不知道为什么没有被用来代替发电机表达式:

if 5 in (data.n for data in myList):
    print "Found it"

But this is hardly much of an improvement over the other approaches, such as this one using any : 但这与其他方法相比几乎没有什么改进,比如这个使用any

if any(data.n == 5 for data in myList):
    print "Found it"

the "if x in thing:" format is strongly preferred, not just because it takes less code, but it also works on other data types and is (to me) easier to read. “if in in thing:”格式是首选格式,不仅因为它占用的代码较少,而且还适用于其他数据类型,并且(对我而言)更易于阅读。

I'm not sure how it's implemented, but I'd expect it to be quite a lot more efficient on datatypes that are stored in a more searchable form. 我不确定它是如何实现的,但我希望它在以更易搜索的形式存储的数据类型上效率更高。 eg. 例如。 sets or dictionary keys. 集或字典键。

The if thing in somelist is the preferred and fastest way. if thing in somelistif thing in somelist是首选且最快的方式。

Under-the-hood that use of the in-operator translates to somelist.__contains__(thing) whose implementation is equivalent to: any((x is thing or x == thing) for x in somelist) . 使用in-operator转换为somelist.__contains__(thing)其实现等同于: any((x is thing or x == thing) for x in somelist)

Note the condition tests identity and then equality. 注意条件测试身份然后是相等。

for i in list
    if i == thingIAmLookingFor
        return True

The above is a terrible way to test whether an item exists in a collection. 以上是测试一个项目是否存在于集合中的可怕方法。 It returns True from the function, so if you need the test as part of some code you'd need to move this into a separate utility function, or add thingWasFound = False before the loop and set it to True in the if statement (and then break), either of which is several lines of boilerplate for what could be a simple expression. 它从函数返回 True ,因此如果您需要将测试作为某些代码的一部分,则需要将其移动到单独的实用程序函数中,或者在循环之前添加thingWasFound = False并在if语句中将其设置为True (和然后打破),其中任何一行都是几行样板,可以是一个简单的表达式。

Plus, if you just use thingIAmLookingFor in list , this might execute more efficiently by doing fewer Python level operations (it'll need to do the same operations, but maybe in C, as list is a builtin type). 另外,如果您只是thingIAmLookingFor in list使用thingIAmLookingFor in list ,则可以通过执行更少的Python级别操作来更有效地执行(它需要执行相同的操作,但可能在C中,因为list是内置类型)。 But even more importantly, if list is actually bound to some other collection like a set or a dictionary thingIAmLookingFor in list will use the hash lookup mechanism such types support and be much more efficient, while using a for loop will force Python to go through every item in turn. 但更重要的是,如果list实际上是绑定到其他集合就像一组或一本字典thingIAmLookingFor in list将使用哈希查找机制这种类型的支持和有效得多 ,而使用for循环将迫使Python来浏览每项目依次。

Obligatory post-script: list is a terrible name for a variable that contains a list as it shadows the list builtin, which can confuse you or anyone who reads your code. 强制性的后脚本: list是一个变量的可怕名称,它包含一个列表,因为它会影响内置list ,这会让您或任何读取代码的人感到困惑。 You're much better off naming it something that tells you something about what it means . 你最好把它命名为能够告诉你它意味着什么的东西。

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

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