Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't "is" keyword work here? [duplicate]

Tags:

python

integer

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:

>>>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.

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?

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.

like image 928
Gnijuohz Avatar asked Dec 19 '13 05:12

Gnijuohz


People also ask

Does duplicate copy Hurt SEO?

Is Duplicate Content Bad For SEO? Officially, Google does not impose a penalty for duplicate content. However, it does filter identical content, which has the same impact as a penalty: a loss of rankings for your web pages.

Why is duplicate content Bad for SEO?

In general, Google doesn't want to rank pages with duplicate content. In fact, Google states that: “Google tries hard to index and show pages with distinct information”. So if you have pages on your site WITHOUT distinct information, it can hurt your search engine rankings.

How does Google identify what content is duplicated?

Google uses a predictive method to detect duplicate content based on URL patterns, which could lead to pages being incorrectly identified as duplicates. In order to prevent unnecessary crawling and indexing, Google tries to predict when pages may contain similar or duplicate content based on their URLs.


2 Answers

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.

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

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

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.

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

like image 147
Tim Peters Avatar answered Sep 22 '22 01:09

Tim Peters


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.

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.

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

like image 39
Lennart Regebro Avatar answered Sep 19 '22 01:09

Lennart Regebro