热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么“is”关键字不在这里工作?[重复]-Whydoesn't“is”keywordworkhere?[duplicate]

Thisquestionalreadyhasananswerhere:这个问题在这里已有答案:“is”operatorbehavesunexpectedly

This question already has an answer here:

这个问题在这里已有答案:

  • “is” operator behaves unexpectedly with integers 11 answers
  • “是”运算符意外地使用整数11个答案

  • How is the 'is' keyword implemented in Python? 10 answers
  • 如何在Python中实现'is'关键字? 10个答案

I know that is is used to compare if two objects are the same but == is for equality. From my experience is always worked for numbers because Python reuse numbers. for example:

我知道这是用来比较两个对象是否相同,但==是为了相等。根据我的经验总是适用于数字,因为Python重用数字。例如:

>>>a = 3
>>>a is 3
True

And I'm used to using is whenever I compare something to a number. But is didn't work for this program below:

每当我将某些东西与数字进行比较时,我习惯使用它。但是下面这个程序没有用:

from collections import namedtuple
# Code taken directly from [Udacity site][1].
# make a basic Link class
Link = namedtuple('Link', ['id', 'submitter_id', 'submitted_time', 'votes',
                           'title', 'url'])

# list of Links to work with
links = [
    Link(0, 60398, 1334014208.0, 109,
         "C overtakes Java as the No. 1 programming language in the TIOBE index.",
         "http://pixelstech.net/article/index.php?id=1333969280"),
    Link(1, 60254, 1333962645.0, 891,
         "This explains why technical books are all ridiculously thick and overpriced",
         "http://prog21.dadgum.com/65.html"),
    Link(23, 62945, 1333894106.0, 351,
         "Learn Haskell Fast and Hard",
         "http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/"),
    Link(2, 6084, 1333996166.0, 81,
         "Announcing Yesod 1.0- a robust, developer friendly, high performance web framework for Haskell",
         "http://www.yesodweb.com/blog/2012/04/announcing-yesod-1-0"),
    Link(3, 30305, 1333968061.0, 270,
         "TIL about the Lisp Curse",
         "http://www.winestockwebdesign.com/Essays/Lisp_Curse.html"),
    Link(4, 59008, 1334016506.0, 19,
         "The Downfall of Imperative Programming. Functional Programming and the Multicore Revolution",
         "http://fpcomplete.com/the-downfall-of-imperative-programming/"),
    Link(5, 8712, 1333993676.0, 26,
         "Open Source - Twitter Stock Market Game - ",
         "http://www.twitstreet.com/"),
    Link(6, 48626, 1333975127.0, 63,
         "First look: Qt 5 makes Javascript a first-class citizen for app development",
         "http://arstechnica.com/business/news/2012/04/an-in-depth-look-at-qt-5-making-Javascript-a-first-class-citizen-for-native-cross-platform-developme.ars"),
    Link(7, 30172, 1334017294.0, 5,
         "Benchmark of Dictionary Structures", "http://lh3lh3.users.sourceforge.net/udb.shtml"),
    Link(8, 678, 1334014446.0, 7,
         "If It's Not on Prod, It Doesn't Count: The Value of Frequent Releases",
         "http://bits.shutterstock.com/?p=165"),
    Link(9, 29168, 1334006443.0, 18,
         "Language proposal: dave",
         "http://davelang.github.com/"),
    Link(17, 48626, 1334020271.0, 1,
         "LispNYC and EmacsNYC meetup Tuesday Night: Large Scale Development with Elisp ",
         "http://www.meetup.com/LispNYC/events/47373722/"),
    Link(101, 62443, 1334018620.0, 4,
         "research!rsc: Zip Files All The Way Down",
         "http://research.swtch.com/zip"),
    Link(12, 10262, 1334018169.0, 5,
         "The Tyranny of the Diff",
         "http://michaelfeathers.typepad.com/michael_feathers_blog/2012/04/the-tyranny-of-the-diff.html"),
    Link(13, 20831, 1333996529.0, 14,
         "Understanding NIO.2 File Channels in Java 7",
         "http://java.dzone.com/articles/understanding-nio2-file"),
    Link(15, 62443, 1333900877.0, 1244,
         "Why vector icons don't work",
         "http://www.pushing-pixels.org/2011/11/04/about-those-vector-icons.html"),
    Link(14, 30650, 1334013659.0, 3,
         "Python - Getting Data Into Graphite - Code Examples",
         "http://coreygoldberg.blogspot.com/2012/04/python-getting-data-into-graphite-code.html"),
    Link(16, 15330, 1333985877.0, 9,
         "Mozilla: The Web as the Platform and The Kilimanjaro Event",
         "https://groups.google.com/forum/?fromgroups#!topic/mozilla.dev.planning/Y9v46wFeejA"),
    Link(18, 62443, 1333939389.0, 104,
         "github is making me feel stupid(er)",
         "http://www.serpentine.com/blog/2012/04/08/github-is-making-me-feel-stupider/"),
    Link(19, 6937, 1333949857.0, 39,
         "BitC Retrospective: The Issues with Type Classes",
         "http://www.bitc-lang.org/pipermail/bitc-dev/2012-April/003315.html"),
    Link(20, 51067, 1333974585.0, 14,
         "Object Oriented C: Class-like Structures",
         "http://cecilsunkure.blogspot.com/2012/04/object-oriented-c-class-like-structures.html"),
    Link(10, 23944, 1333943632.0, 188,
         "The LOVE game framework version 0.8.0 has been released - with GLSL shader support!",
         "https://love2d.org/forums/viewtopic.php?f=3&t=8750"),
    Link(22, 39191, 1334005674.0, 11,
         "An open letter to language designers: Please kill your sacred cows. (megarant)",
         "http://joshondesign.com/2012/03/09/open-letter-language-designers"),
    Link(21, 3777, 1333996565.0, 2,
         "Developers guide to Garage48 hackatron",
         "http://martingryner.com/developers-guide-to-garage48-hackatron/"),
    Link(24, 48626, 1333934004.0, 17,
         "An R programmer looks at Julia",
         "http://www.r-bloggers.com/an-r-programmer-looks-at-julia/")]


# links is a list of Link objects. Links have a handful of properties. For
# example, a Link's number of votes can be accessed by link.votes if "link" is a
# Link.

# make the function query() return a list of Links submitted by user 62443, by
# submission time ascending

def query():
    print "hello"
    print [link for link in links if link.submitter_id == 62443] # is does not work
    return sorted([link for link in links if link.submitter_id == 62443],key = lambda x: x[2])
query()

When I used is inside the query function like this [link for link in links if link.submitter_id is 62443] I'll get an empty list. But if I use ==, it worked fine.

当我使用的是这样的查询函数内部[链接链接链接如果link.submitter_id是62443]我将得到一个空列表。但如果我使用==,它工作正常。

For the most part, the code was directly taken from the udacity site but I also tried it on my local machine. The same result. So I think the numbers are now different objects in this case but why? Is there a need for this?

在大多数情况下,代码直接从udacity网站获取,但我也在我的本地机器上尝试过。同样的结果。所以我认为这个数字现在是不同的对象,但为什么呢?有这个需要吗?

EDIT: Yes. I admit this question is duplicate and should be closed. But it's duplicate with the first post not the second. I didn't know that question before posting this.

编辑:是的。我承认这个问题是重复的,应该关闭。但它与第一​​篇文章不同,而不是第二篇文章。在发布之前我不知道这个问题。

My problem was that I thought number objects would always be reused.

我的问题是我认为数字对象总是会被重用。

Thanks to everyone, I got rid of a bad habit.

感谢大家,我摆脱了一个坏习惯。

6 个解决方案

#1


9  

There's no answer to your question short of digging into details of the implementation of the specific version of Python you're using. Nothing is defined about whether a == b implies a is b when a and b are numbers. It's often true, and especially for "little integers", due to that CPython keeps a cache of little integer objects and usually (not always!) returns the same object for a given small integer value. But nothing about that is defined, guaranteed, or even always the same across releases.

除了深入研究您正在使用的特定Python版本的实现细节之外,您的问题没有答案。当a和b是数字时,没有定义a == b是否暗示a是b。这通常是正确的,特别是对于“小整数”,因为CPython保留了一些小整数对象的缓存,并且通常(并非总是!)为给定的小整数值返回相同的对象。但是没有任何关于它的定义,保证,甚至在各个版本中始终相同。

Thinking about memory addresses can be mildly helpful, since that's how id() is implemented in CPython. But other implementations use different implementations for id(). For example, I was told that id() was a major pain to implement in Jython (Python implemented in Java), since Java is free to move objects around in memory during garbage collection (CPython does not: in CPython an object always occupies the memory originally allocated for it, until the object becomes trash).

考虑内存地址可能会有一些帮助,因为这就是在CPython中实现id()的方式。但是其他实现对id()使用不同的实现。例如,我被告知id()是在Jython中实现的一个主要难题(用Java实现的Python),因为Java在垃圾收集期间可以自由地在内存中移动对象(CPython没有:在CPython中,对象总是占用最初为它分配的内存,直到对象变为垃圾)。

The only intended - and supported - use for is is to check whether two names for objects in fact resolve to the very same object. For example, regardless of the type of b, after

唯一用于和支持的用途是检查对象的两个名称是否实际上解析为同一个对象。例如,不管b的类型如何

a = b

it must be the case that

一定是这样的

a is b

is True. And that's sometimes useful.

是真的。这有时很有用。

_sentinel = object() # create a unique object

def somefunc(optiOnal=_sentinel):
    if optional is _sentinel:  # we know for sure nothing was passed
        ...

The other main use is for the handful of objects guaranteed to be singletons. None, True and False are examples of that, and indeed it's idiomatic to write:

另一个主要用途是保证为单身的少数对象。没有,是真是假的例子,实际上它写的是惯用的:

if a is None:

instead of:

if a == None:

The first way succeeds if and only if a is in fact bound to the the singleton None object, but the second way may succeed if a is of any type such that a.__eq__(None) returns True.

当且仅当a实际上绑定到单例None对象时,第一种方式成功,但如果a是任何类型,使得.__ eq __(None)返回True,则第二种方式可能成功。

Don't use is for numbers. That's insane ;-)

不要用于数字。那太疯狂了;-)

#2


5  

You are correct in that is checks identity, if the two variables are the same object, and that == is used to check equality, if the objects are equal. (What equal means is decided by the involved classes).

你是正确的是检查身份,如果两个变量是同一个对象,并且==用于检查相等性,如果对象是相等的。 (所涉及的等级决定了相同的手段)。

And you are correct that using is to check if two numbers are equal often works, because Python reuse numbers, so often when they are equal, they are also identical.

你是正确的,使用是检查两个数字是否相等通常是有效的,因为Python重用数字,所以通常当它们相等时,它们也是相同的。

But you do notice how that sounds. Should you check if two numbers are equal, by using the identity check? No, of course not. You should use the equality check to check if objects are equal. It's as simple as that.

但你确实注意到这听起来如何。你应该通过身份检查来检查两个号码是否相等吗?不,当然不。您应该使用相等性检查来检查对象是否相等。就这么简单。

That you often can use the identity check to check the equality of numbers is just a side-effect of Python reusing numbers, which it does to save memory, and which is an implementation detail.

您经常可以使用身份检查来检查数字的相等性只是Python重用数字的副作用,它可以节省内存,这是一个实现细节。

Besides, in Python 3 == 3.0, but 3 is not 3.0. So you should use == for that reason.

此外,在Python 3 == 3.0中,但3不是3.0。因此你应该使用==。

#3


1  

There are two parts to this question

这个问题分为两部分

  1. is does not checks for equality, it just checks for identity. Two objects have same identity iff they are same objects (with same identity i.e. id(a) == id(b))

    是不检查相等性,它只是检查身份。如果两个对象是相同的对象(具有相同的标识,即id(a)== id(b)),则它们具有相同的标识

    >>> a = 10
    >>> b = a
    >>> id(a), id(b)
    (30388628, 30388628)
    
  2. CPython as Implemented (may be for others) certain numbers range of integers within a certain limit, they are cached so even though they are different objects, yet they have the same identity

    CPython as Implemented(可能是为其他人)某些数字范围内的整数在一定限度内,它们被缓存,即使它们是不同的对象,但它们具有相同的身份

Thus

>>> a is 200
True
>>> a = 2000
>>> a is 2000
False

#4


0  

This is because is compares identities:

这是因为比较身份:

>>> a = 10
>>> id(a)
30967348
>>> id(10)
30967348
>>> a is 10
True
>>> a += 1
>>> a
11
>>> id(a)
30967336
>>> id(11)
30967336
>>> a is 11
True
>>> a = 106657.334
>>> id(a)
44817088
>>> id(106657.334)
31000752
>>> a is 106657.334
False
>>> a == 106657.334
True

#5


0  

is used to compare identity.

用于比较身份。

In [26]: a = 3

In [27]: a is 3
Out[27]: True

In [28]: id(a)
Out[28]: 140479182211448

In [29]: id(3)
Out[29]: 140479182211448

Extending same to the above example.

将其扩展到上面的例子。

In [32]: for link in links:
    print id(link.submitter_id), id(62443), id(link.submitter_id) == id(62443), link.submitter_id

....:

140479184066728 140479184065152 False 60398
140479184066872 140479184065152 False 60254
140479184065688 140479184065152 False 62945
140479184064984 140479184065152 False 6084
140479184064648 140479184065152 False 30305
140479184063416 140479184065152 False 59008
140479184063608 140479184065152 False 8712
140479184063752 140479184065152 False 48626
140479184064352 140479184065152 False 30172
140479185936456 140479184065152 False 678
140479185966096 140479184065152 False 29168
140479184063752 140479184065152 False 48626
140479185936888 140479184065152 False 62443
140479184052336 140479184065152 False 10262
140479184061232 140479184065152 False 20831
140479185936888 140479184065152 False 62443
140479184057712 140479184065152 False 30650
140479185957880 140479184065152 False 15330
140479185936888 140479184065152 False 62443
140479185959760 140479184065152 False 6937
140479184061528 140479184065152 False 51067
140479184058728 140479184065152 False 23944
140479185944264 140479184065152 False 39191
140479184062568 140479184065152 False 3777
140479184063752 140479184065152 False 48626

Use is when checking for identity.

用于检查身份。

Ref: String comparison in Python: is vs. ==

参考:Python中的字符串比较:是与==

#6


0  

The is operator is used to compare the identities of the two objects So basically You're comparing whether the objects have the same identity, not whether they are equal

is运算符用于比较两个对象的身份所以基本上你要比较对象是否具有相同的身份,而不是它们是否相等

So if you print the id's of the objects involved using the id() function their id's are different so the is operator doesn't work in this case:

因此,如果使用id()函数打印所涉及对象的id,则它们的id不同,因此is运算符在这种情况下不起作用:

>>>print [(id(link),id(62443)) for link in links if link.submitter_id == 62443]
[(28741560, 21284824), (28860576, 21284824), (28860744, 21284824)]

Although just because two objects are similar there identities might not be the same

虽然仅仅因为两个对象相似,但身份可能不一样


Note: After an object is garbage collected, it's id is available to be reused. So the use of the is operator is actually somewhat discouraged

注意:对象被垃圾回收后,可以重用它的id。因此,实际上有人不鼓励使用is运算符


推荐阅读
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
author-avatar
哈哈不会玩NO1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有