122

演算子は変数のis値とは一致しませんが、インスタンス自体と一致します。

それは本当にどういう意味ですか?

x名前を付けて両方の変数に同じ値を割り当てる2つの変数を宣言しましたが、演算子yを使用するとfalseが返されます。is

説明が必要です。これが私のコードです。

x = [1, 2, 3]
y = [1, 2, 3]

print(x is y)  # It prints false!
4

11 に答える 11

201

isあなたはオペレーターが何をテストするかを誤解しました。2つの変数が同じ値を持っているかどうかではなく、2つの変数が同じオブジェクトを指しているかどうかをテストします。

isオペレーター向けのドキュメントから:

演算子isis notオブジェクトIDのテスト:とが同じオブジェクトx is yである場合にのみtrueになります。xy

==代わりに演算子を使用してください。

print(x == y)

これは印刷しTrueます。xyは2つの別々のリストです。

x[0] = 4
print(y)  # prints [1, 2, 3]
print(x == y)   # prints False

id()この関数を使用すると、それが表示されxyさまざまな識別子が使用されます。

>>> id(x)
4401064560
>>> id(y)
4401098192

ただし、に割り当てる場合はyx両方が同じオブジェクトを指します。

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

is両方が同じオブジェクトであることを示し、を返しますTrue

Pythonでは、名前は値を参照する単なるラベルであることに注意してください。複数の名前で同じオブジェクトを指すようにすることができます。is2つの名前が1つの同じオブジェクトを指しているかどうかを示します。==2つの名前が同じ値を持つオブジェクトを参照しているかどうかを示します。

于 2012-11-30T17:40:23.050 に答える
69

別の重複は、2つの等しい文字列が一般的に同一ではない理由を尋ねていましたが、ここでは実際には答えられていません。

>>> x = 'a' 
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False

では、なぜそれらは同じ文字列ではないのですか?特にこれを考えると:

>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True

2番目の部分を少し延期しましょう。最初のものはどうして真実でしょうか?

インタプリタには、文字列値を文字列オブジェクトにマッピングするテーブルである「インターンテーブル」が必要になるため、内容を使用して新しい文字列を作成しようとするたびに'abc'、同じオブジェクトが返されます。ウィキペディアには、インターンがどのように機能するかについてのより詳細な議論があります。

また、Pythonは文字列インターンテーブルがあります。このメソッドを使用して、文字列を手動でインターンできますsys.intern

実際、Pythonは不変の型を自動的にインターンすることができますが、そうする必要はありません。実装が異なれば、異なる値がインターンされます。

CPython(使用している実装がわからない場合に使用している実装)はFalse、文字列(または大きな整数、小さなタプルなど)ではなく、小さな整数とのようないくつかの特別なシングルトンを自動インターンします。あなたはこれをかなり簡単に見ることができます:

>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False

OK、でもなぜ同じだったzの?w

これは、インタープリターが自動的にインターンするのではなく、コンパイラーのフォールディング値です。

同じコンパイル時の文字列が同じモジュールに2回表示される場合(これは正確に定義するのが難しいことを意味します。、、、はすべて異なるリテラルですが同じ文字列であるため、文字列リテラルと同じではありませんがr'abc'、理解しやすいです。直感的に)、コンパイラは2つの参照を使用して文字列のインスタンスを1つだけ作成します。'abc''a' 'b' 'c'

実際、コンパイラーはさらに先に進むことができます。オプティマイザーによって'ab' + 'c'変換できます。その場合、同じモジュール内の定数と'abc'一緒に折りたたむことができます。'abc'

繰り返しますが、これはPythonで許可されているものですが、必須ではありません。ただし、この場合、CPythonは常に小さな文字列(および、たとえば小さなタプル)を折り畳みます。(ただし、対話型インタープリターのステートメントごとのコンパイラーは、module-at-a-timeコンパイラーと同じ最適化を実行しないため、対話式でまったく同じ結果が表示されることはありません。)


それで、あなたはプログラマーとしてこれについて何をすべきですか?

まあ…何も。2つの不変の値が同一であるかどうかを気にする理由はほとんどありません。a is bの代わりにいつ使用できるかを知りたい場合a == bは、間違った質問をしていることになります。a == b次の2つの場合を除いて、常に使用してください。

  • のようなシングルトン値とのより読みやすい比較のためにx is None
  • x変更可能な値の場合、変更がに影響するかどうかを知る必要がある場合y
于 2014-09-10T05:38:57.873 に答える
8

isそれらが実際に同じオブジェクトである場合にのみtrueを返します。それらが同じである場合、一方への変更はもう一方にも表示されます。違いの例を次に示します。

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]
于 2012-11-30T17:44:11.033 に答える
8

重複する質問によって促されると、このアナロジーは機能する可能性があります。

# - Darling, I want some pudding!
# - There is some in the fridge.

pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True

# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.

pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False
于 2014-09-10T04:56:26.477 に答える
6

isis notはPythonの2つのID演算子です。is演算子は変数の値を比較しませんが、変数のIDを比較します。このことを考慮:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>

上記の例は、ID(Cpythonではメモリアドレスにすることもできます)がと(値が同じであっても)の両方aで異なることを示しています。bそのa is bため、両方のオペランドのIDが一致しないため、falseが返されます。ただし、と言うと、操作は両方のオペランドに同じ値が割り当てられているかどうかのみを検証するa == bため、trueを返します。==

興味深い例(エクストラグレードの場合):

>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>

上記の例では、abは2つの異なる変数ですが、がa is b返されTrueます。これは、のタイプがa不変intオブジェクトであるためです。そのため、Python(メモリを節約すると思います)はb、同じ値で作成されたときに同じオブジェクトを割り当てました。したがって、この場合、変数のIDは一致し、であるa is bことが判明しましたTrue

これは、すべての不変オブジェクトに適用されます。

>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>

お役に立てば幸いです。

于 2015-12-03T01:42:55.667 に答える
4

x is yと同じでid(x) == id(y)、オブジェクトのIDを比較します。

@ tomasz-kurganが以下のコメントで指摘しているように、is演算子は特定のオブジェクトで異常に動作します。

例えば

>>> class A(object):
...   def foo(self):
...     pass
... 
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True

参照;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24

于 2016-07-29T11:59:35.063 に答える
3

ここで小さな整数を確認できます。257を超える数値は小さな整数ではないため、別のオブジェクトとして計算されます。

==この場合、代わりに使用することをお勧めします。

詳細については、こちらをご覧ください:http: //docs.python.org/2/c-api/int.html

于 2012-11-30T17:42:40.800 に答える
2

Xは配列を指し、Yは別の配列を指します。これらの配列は同一ですが、isオペレーターは同一ではないこれらのポインターを調べます。

于 2012-11-30T17:40:31.623 に答える
1

オブジェクトID、つまり、変数がメモリ内の同じオブジェクトを参照しているかどうかを比較します。これは==、JavaまたはCの場合と似ています(ポインターを比較する場合)。

于 2012-11-30T17:41:35.523 に答える
1

果物の簡単な例

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist is newfruitlist )
print ( fruitlist is verynewfruitlist )
print ( newfruitlist is verynewfruitlist )

出力:

True
False
False

やってみたら

fruitlist = [" apple ", " banana ", " cherry ", " durian "]
newfruitlist = fruitlist
verynewfruitlist = fruitlist [:]
print ( fruitlist == newfruitlist )
print ( fruitlist == verynewfruitlist )
print ( newfruitlist == verynewfruitlist )

出力は異なります:

True
True
True

これは、==演算子が変数の内容だけを比較するためです。2つの変数のIDを比較するには、is演算子を使用します

識別番号を印刷するには:

print ( id( variable ) )
于 2018-10-29T19:34:51.557 に答える
-4

演算子は、のis英語版に他なりません==。2つのリストのIDが異なるため、答えは誤りです。あなたが試すことができます:

a=[1,2,3]
b=a
print(b is a )#True

*両方のリストのIDが同じになるため

于 2019-12-24T07:58:10.360 に答える