Có sự khác biệt nào giữa những người khác


630

My Google-fu đã thất bại tôi.

Trong Python, hai bài kiểm tra sau đây có tương đương nhau không?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

Điều này có đúng với các đối tượng mà bạn sẽ so sánh các trường hợp ( listnói) không?

Được rồi, vì vậy loại câu trả lời câu hỏi của tôi:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

Vì vậy, ==kiểm tra giá trị nơi iskiểm tra để xem nếu chúng là cùng một đối tượng?

Câu trả lời:


928

issẽ trả về Truenếu hai biến trỏ đến cùng một đối tượng, ==nếu các đối tượng được gọi bởi các biến bằng nhau.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

Trong trường hợp của bạn, thử nghiệm thứ hai chỉ hoạt động vì Python lưu trữ các đối tượng số nguyên nhỏ, đây là một chi tiết triển khai. Đối với số nguyên lớn hơn, điều này không hoạt động:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

Điều tương tự cũng đúng với chuỗi ký tự:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

Xin vui lòng xem câu hỏi này là tốt.


2
Tôi thấy rằng: echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foođầu ra : False True False.
ahuigo

Bạn đã mất tôi với b = a[:]phần sao chép danh sách toán tử lát, vì vậy tôi đã chỉnh sửa câu trả lời của bạn để có một nhận xét ở đó. Có vẻ như tôi đã đạt đến ngưỡng để không phải xem xét các chỉnh sửa của mình trước khi chúng được áp dụng, vì vậy hy vọng điều đó thật tuyệt với bạn. Bất kể, đây là một tài liệu tham khảo hữu ích cho cách sao chép danh sách mà tôi đã gặp và phải tham khảo để tìm ra những gì bạn đang làm: stackoverflow.com/a/2612815/4561887
Gabriel Staples

Một cách khác để chứng minh sự khác biệt là bằng cách so sánh các đối tượng thuộc các loại khác nhau, tất nhiên, có thể không bao giờ là cùng một đối tượng nhưng vẫn so sánh bằng nhau khi sử dụng ==. Vì vậy, 5.0ví dụ, là một giá trị dấu phẩy động, trong khi 5là một số nguyên. Nhưng 5.0 == 5vẫn sẽ trả lại Truevì chúng đại diện cho cùng một giá trị. Về mặt hiệu năng và gõ vịt, isluôn được người phiên dịch kiểm tra bằng cách so sánh các địa chỉ bộ nhớ của toán hạng, trong khi ==đó, tùy thuộc vào đối tượng để quyết định xem nó có tự xác định bằng một thứ khác không.
Bachsau

3
1000 is 10**3ước tính là True trong Python 3.7 vì 10 ** 3 là loại int. Nhưng 1000 is 1e3đánh giá thành Sai vì 1e3 là loại float.
Ahmed Fasih

@AhmedFasih Việc 1000 is 10**3có đúng hay không là tùy thuộc vào việc triển khai và phụ thuộc vào trình biên dịch đánh giá trước biểu thức 10**3. x=10; 1000 is x**3đánh giá để False.
chepner

313

Có một quy tắc đơn giản để cho bạn biết khi nào nên sử dụng ==hay is.

  • ==là cho bình đẳng giá trị . Sử dụng nó khi bạn muốn biết nếu hai đối tượng có cùng giá trị.
  • islà cho bình đẳng tham khảo . Sử dụng nó khi bạn muốn biết nếu hai tài liệu tham khảo đề cập đến cùng một đối tượng.

Nói chung, khi bạn so sánh một cái gì đó với một loại đơn giản, bạn thường kiểm tra sự bình đẳng giá trị , vì vậy bạn nên sử dụng ==. Ví dụ, ý định của ví dụ của bạn có lẽ là để kiểm tra xem x có giá trị bằng 2 ( ==) hay không, có xnghĩa là có liên quan đến cùng một đối tượng là 2 hay không.


Một điều khác cần lưu ý: do cách triển khai tham chiếu CPython hoạt động, bạn sẽ nhận được kết quả không nhất quán và không nhất quán nếu bạn sử dụng nhầm isđể so sánh cho đẳng thức tham chiếu trên số nguyên:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

Đó là khá nhiều những gì chúng ta mong đợi: abcó cùng giá trị, nhưng là các thực thể riêng biệt. Nhưng những gì về điều này?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

Điều này không phù hợp với kết quả trước đó. Những gì đang xảy ra ở đây? Nó chỉ ra việc triển khai tham chiếu của Python lưu trữ các đối tượng số nguyên trong phạm vi -5..256 như các trường hợp đơn lẻ vì lý do hiệu năng. Đây là một ví dụ minh họa điều này:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

Đây là một lý do rõ ràng khác không nên sử dụng is: hành vi được dành cho việc triển khai khi bạn sử dụng sai mục đích cho sự bình đẳng giá trị.


Liên quan đến ví dụ đầu tiên về a=500b=500, chỉ muốn chỉ ra rằng nếu bạn đặt abchuyển đổi giữa [-5, 256], a is bthực sự sẽ trả về True. Thêm thông tin tại đây: stackoverflow.com/q/306313/7571052
AsheKetchum

1
@AsheKetchum, vâng, lưu ý rằng tôi đã viết "Hóa ra việc triển khai tham chiếu của Python lưu trữ các đối tượng số nguyên trong phạm vi -5..256 như các trường hợp đơn lẻ vì lý do hiệu suất."
John Women'sella

34

==xác định nếu các giá trị bằng nhau, trong khi isxác định nếu chúng là cùng một đối tượng.


32

Có sự khác biệt giữa ==istrong Python?

Vâng, họ có một sự khác biệt rất quan trọng.

==: kiểm tra sự bằng nhau - ngữ nghĩa là các đối tượng tương đương (không nhất thiết phải cùng một đối tượng) sẽ kiểm tra như nhau. Như tài liệu nói :

Các toán tử <,>, ==,> =, <= và! = So sánh giá trị của hai đối tượng.

is: kiểm tra danh tính - ngữ nghĩa là đối tượng (như được giữ trong bộ nhớ) đối tượng. Một lần nữa, tài liệu nói :

Các toán tử isis notkiểm tra nhận dạng đối tượng: x is ylà đúng khi và chỉ khi xylà cùng một đối tượng. Nhận dạng đối tượng được xác định bằng cách sử dụng id()chức năng. x is not ymang lại giá trị thật ngược.

Do đó, việc kiểm tra danh tính cũng giống như kiểm tra sự bằng nhau của ID của các đối tượng. Đó là,

a is b

giống như:

id(a) == id(b)

trong đó idhàm dựng sẵn trả về một số nguyên "được đảm bảo là duy nhất trong số các đối tượng hiện có đồng thời" (xem help(id)) và ở đâu ablà bất kỳ đối tượng tùy ý nào.

Hướng dẫn sử dụng khác

Bạn nên sử dụng những so sánh này cho ngữ nghĩa của họ. Sử dụng isđể kiểm tra danh tính và ==kiểm tra sự bình đẳng.

Vì vậy, nói chung, chúng tôi sử dụng isđể kiểm tra danh tính. Điều này thường hữu ích khi chúng ta đang kiểm tra một đối tượng chỉ tồn tại một lần trong bộ nhớ, được gọi là "singleton" trong tài liệu.

Các trường hợp sử dụng isbao gồm:

  • None
  • giá trị enum (khi sử dụng Enums từ mô-đun enum)
  • mô-đun thường
  • thường là các đối tượng lớp kết quả từ định nghĩa lớp
  • thường là các đối tượng hàm do các định nghĩa hàm
  • bất cứ điều gì khác chỉ nên tồn tại một lần trong bộ nhớ (nói chung là tất cả các singletons)
  • một đối tượng cụ thể mà bạn muốn theo danh tính

Các trường hợp sử dụng thông thường ==bao gồm:

  • số, bao gồm số nguyên
  • dây
  • danh sách
  • bộ
  • từ điển
  • đối tượng biến đổi tùy chỉnh
  • đối tượng bất biến dựng sẵn khác, trong hầu hết các trường hợp

Các trường hợp sử dụng chung, một lần nữa, cho ==, là đối tượng mà bạn muốn thể không phải là cùng một đối tượng, thay vào đó nó có thể là một tương đương một

PEP 8 hướng

PEP 8, hướng dẫn kiểu Python chính thức cho thư viện chuẩn cũng đề cập đến hai trường hợp sử dụng chois :

Việc so sánh với các singletons như vậy Nonephải luôn luôn được thực hiện với ishoặc is not, không bao giờ là các toán tử đẳng thức.

Ngoài ra, hãy cẩn thận if xkhi viết khi bạn thực sự có ý nghĩa if x is not None- ví dụ như khi kiểm tra xem một biến hoặc đối số mặc định None được đặt thành một số giá trị khác. Giá trị khác có thể có một loại (chẳng hạn như một thùng chứa) có thể sai trong bối cảnh boolean!

Suy ra sự bình đẳng từ bản sắc

Nếu islà đúng, sự bình đẳng thường có thể được suy ra - về mặt logic, nếu một đối tượng là chính nó, thì nó nên kiểm tra tương đương với chính nó.

Trong hầu hết các trường hợp logic này là đúng, nhưng nó phụ thuộc vào việc thực hiện __eq__phương pháp đặc biệt. Như các tài liệu nói,

Hành vi mặc định để so sánh bằng ( ==!=) dựa trên danh tính của các đối tượng. Do đó, so sánh bình đẳng của các thể hiện có cùng một danh tính dẫn đến sự bình đẳng và so sánh bình đẳng của các thể hiện với các danh tính khác nhau dẫn đến sự bất bình đẳng. Một động lực cho hành vi mặc định này là mong muốn rằng tất cả các đối tượng nên phản xạ (tức là x là y ngụ ý x == y).

và vì lợi ích của tính nhất quán, khuyến nghị:

So sánh bình đẳng nên được phản xạ. Nói cách khác, các đối tượng giống hệt nhau nên so sánh bằng nhau:

x is y ngụ ý x == y

Chúng ta có thể thấy rằng đây là hành vi mặc định cho các đối tượng tùy chỉnh:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

Thông tin chi tiết cũng thường đúng - nếu đôi khi kiểm tra là không bằng nhau, bạn thường có thể suy ra rằng chúng không phải là cùng một đối tượng.

Vì các thử nghiệm cho sự bình đẳng có thể được tùy chỉnh, suy luận này không phải lúc nào cũng đúng với tất cả các loại.

Một ngoại lệ

Một ngoại lệ đáng chú ý là nan- nó luôn kiểm tra là không bằng chính nó:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

Kiểm tra danh tính có thể là một kiểm tra nhanh hơn nhiều so với kiểm tra sự bình đẳng (có thể yêu cầu kiểm tra đệ quy các thành viên).

Nhưng nó không thể được thay thế cho sự bình đẳng nơi bạn có thể tìm thấy nhiều hơn một đối tượng là tương đương.

Lưu ý rằng so sánh sự bình đẳng của danh sách và bộ dữ liệu sẽ cho rằng danh tính của các đối tượng là bằng nhau (vì đây là kiểm tra nhanh). Điều này có thể tạo ra mâu thuẫn nếu logic không nhất quán - vì nó dành cho nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

Một câu chuyện thận trọng:

Câu hỏi đang cố gắng sử dụng isđể so sánh các số nguyên. Bạn không nên cho rằng một thể hiện của một số nguyên là cùng một thể hiện với một tham chiếu khác. Câu chuyện này giải thích tại sao.

Một nhà bình luận có mã dựa trên thực tế là các số nguyên nhỏ (bao gồm từ 5 đến 256) là các singletons trong Python, thay vì kiểm tra sự bằng nhau.

Wow, điều này có thể dẫn đến một số lỗi quỷ quyệt. Tôi đã có một số mã kiểm tra nếu a là b, hoạt động như tôi muốn vì a và b thường là các số nhỏ. Lỗi chỉ xảy ra hôm nay, sau sáu tháng sản xuất, vì a và b cuối cùng đủ lớn để không bị lưu vào bộ nhớ cache. - gwg

Nó đã làm việc trong sự phát triển. Nó có thể đã vượt qua một số khó khăn.

Và nó đã hoạt động trong sản xuất - cho đến khi mã kiểm tra một số nguyên lớn hơn 256, tại thời điểm đó nó đã thất bại trong sản xuất.

Đây là một lỗi sản xuất có thể đã bị bắt trong đánh giá mã hoặc có thể với trình kiểm tra kiểu.

Hãy để tôi nhấn mạnh: không sử dụng isđể so sánh các số nguyên.


"Không sử dụng là hoàn toàn" cũng sẽ là một quy tắc tốt. Thành ngữ is Nonelà một ngoại lệ, nhưng điều đó cũng có == Nonetác dụng ...
Jean-François Fabre

@ Jean-FrançoisFabre Một ngoại lệ khác: Tài liệu chính thức dường như khuyên bạn nên sử dụng isđể so sánh Enums.
Arthur

@Arthur Tôi đã thêm một danh sách các trường hợp sử dụng ...
Aaron Hall

19

Sự khác biệt giữa isvà là ==gì?

==islà so sánh khác nhau! Như những người khác đã nói:

  • == so sánh các giá trị của các đối tượng.
  • is so sánh các tài liệu tham khảo của các đối tượng.

Trong tên Python đề cập đến các đối tượng, ví dụ trong trường hợp này value1value2tham chiếu đến một intcá thể lưu trữ giá trị 1000:

value1 = 1000
value2 = value1

nhập mô tả hình ảnh ở đây

Bởi vì value2đề cập đến cùng một đối tượng is==sẽ cho True:

>>> value1 == value2
True
>>> value1 is value2
True

Trong ví dụ sau, tên value1value2tham chiếu đến các inttrường hợp khác nhau , ngay cả khi cả hai lưu trữ cùng một số nguyên:

>>> value1 = 1000
>>> value2 = 1000

nhập mô tả hình ảnh ở đây

Bởi vì giá trị như nhau (số nguyên) được lưu trữ ==sẽ được True, mà lý do tại sao nó thường được gọi là "giá trị so sánh". Tuy nhiên issẽ trở lại Falsevì đây là những đối tượng khác nhau:

>>> value1 == value2
True
>>> value1 is value2
False

Khi nào nên sử dụng?

Nói chung islà một so sánh nhanh hơn nhiều. Đó là lý do tại sao bộ đệm CPython (hoặc có thể sử dụng lại sẽ là thuật ngữ tốt hơn) một số đối tượng nhất định như số nguyên nhỏ, một số chuỗi, v.v. Nhưng điều này nên được coi là chi tiết triển khai có thể (ngay cả khi không thể) thay đổi tại bất kỳ thời điểm nào mà không cần cảnh báo.

Bạn chỉis nên sử dụng nếu bạn:

  • muốn kiểm tra xem hai đối tượng có thực sự là cùng một đối tượng không (không chỉ là "giá trị" giống nhau). Một ví dụ có thể là nếu bạn sử dụng một đối tượng singleton là hằng số.
  • muốn so sánh một giá trị với hằng số Python . Các hằng số trong Python là:

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • các lớp (ví dụ int is inthoặc int is float)
    • có thể có các hằng số bổ sung trong các mô đun tích hợp hoặc mô đun bên thứ 3. Ví dụ np.ma.maskedtừ mô-đun NumPy)

Trong mọi trường hợp khác, bạn nên sử dụng== để kiểm tra sự bình đẳng.

Tôi có thể tùy chỉnh hành vi không?

Có một số khía cạnh ==chưa được đề cập trong các câu trả lời khác: Đó là một phần của "Mô hình dữ liệu" của Pythons . Điều đó có nghĩa là hành vi của nó có thể được tùy chỉnh bằng __eq__phương pháp. Ví dụ:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

Đây chỉ là một ví dụ nhân tạo để minh họa rằng phương thức này thực sự được gọi là:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

Lưu ý rằng theo mặc định (nếu không có cách triển khai nào khác __eq__có thể được tìm thấy trong lớp hoặc siêu lớp) __eq__sử dụng is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

Vì vậy, điều thực sự quan trọng là phải thực hiện __eq__nếu bạn muốn "nhiều hơn" so với chỉ so sánh tham chiếu cho các lớp tùy chỉnh!

Mặt khác, bạn không thể tùy chỉnh iskiểm tra. Nó sẽ luôn so sánh chỉ khi bạn có cùng tham chiếu.

Những so sánh này sẽ luôn trả về một boolean?

Bởi vì __eq__có thể được thực hiện lại hoặc ghi đè, nó không bị giới hạn trả về Truehoặc False. Nó có thể trả về bất cứ thứ gì (nhưng trong hầu hết các trường hợp, nó sẽ trả về boolean!).

Ví dụ với mảng NumPy, ==sẽ trả về một mảng:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

Nhưng isséc sẽ luôn trở lại Truehoặc False!


1 Như Aaron Hall đã đề cập trong các ý kiến:

Nói chung, bạn không nên thực hiện bất kỳ is Truehoặc is Falsekiểm tra nào vì người ta thường sử dụng các "kiểm tra" này trong ngữ cảnh ngầm chuyển đổi điều kiện thành một boolean (ví dụ như trong một iftuyên bố). Vì vậy, việc is Trueso sánh diễn viên boolean ngầm đang thực hiện nhiều công việc hơn là chỉ thực hiện diễn viên boolean - và bạn giới hạn bản thân trong booleans (không được coi là pythonic).

Giống như đề cập PEP8:

Đừng so sánh các giá trị boolean với Truehoặc Falsesử dụng ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

2
Tôi sẽ không đồng ý với khẳng định của bạn để so sánh "hằng số" với is- các tên trỏ đến booleans nên được kiểm tra với bối cảnh boolean - như if __debug__:hoặc if not __debug__:. Bạn không bao giờ nên làm if __debug__ is True:hoặc if __debug__ == True:- hơn nữa, một hằng số chỉ là một giá trị ngữ nghĩa không đổi, không phải là một đơn, do đó kiểm tra istrong trường hợp đó là không chính xác về mặt ngữ nghĩa. Tôi thách bạn tìm một nguồn để hỗ trợ các xác nhận của bạn - Tôi không nghĩ bạn sẽ tìm thấy một nguồn.
Aaron Hall

@AaronHall Điều gì khiến bạn nghĩ rằng các hằng số không phải là singletons? Lưu ý rằng chỉ None, True, False__debug__là những gì bạn sẽ gọi là "giá trị ngữ nghĩa liên tục", bởi vì họ không thể được bố trí. Nhưng tất cả trong số họ là singletons.
MSeifert

Đọc PEP 8 - Ctrl-F và tìm từ "tệ hơn". - Nếu bạn không hài lòng, bạn sẽ sử dụng self.assertTrue
Aaron Hall

@AaronHall Trong một số trường hợp bạn thực sự cần is Truehoặc if Falsekiểm tra (nhưng vâng, đây là những thứ khá hiếm - nhưng nếu bạn làm chúng, bạn có thể sử dụng chúng is). Đó là lý do tại sao ngay cả CPython đôi khi sử dụng chúng (ví dụ ở đây hoặc ở đây )
MSeifert

19

Chúng hoàn toàn khác nhau . iskiểm tra danh tính đối tượng, trong khi ==kiểm tra sự bằng nhau (một khái niệm phụ thuộc vào hai loại toán hạng).

Chỉ có một sự trùng hợp may mắn là " is" dường như hoạt động chính xác với các số nguyên nhỏ (ví dụ 5 == 4 + 1). Đó là bởi vì CPython tối ưu hóa việc lưu trữ các số nguyên trong phạm vi (-5 đến 256) bằng cách biến chúng thành singletons . Hành vi này hoàn toàn phụ thuộc vào việc thực hiện và không được bảo đảm để được bảo tồn dưới mọi hình thức hoạt động biến đổi nhỏ.

Ví dụ, Python 3.5 cũng tạo ra các chuỗi đơn ngắn, nhưng việc cắt chúng sẽ phá vỡ hành vi này:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False


6

Câu trả lời của bạn là đúng. Các isnhà điều hành so sánh danh tính của hai đối tượng. Các ==nhà điều hành so sánh giá trị của hai đối tượng.

Danh tính của một đối tượng không bao giờ thay đổi một khi nó đã được tạo ra; bạn có thể nghĩ về nó như là địa chỉ của đối tượng trong bộ nhớ.

Bạn có thể kiểm soát hành vi so sánh của các giá trị đối tượng bằng cách xác định một __cmp__phương thức hoặc một phương thức so sánh phong phú như thế nào __eq__.



3

Tóm lại, iskiểm tra xem hai tham chiếu có trỏ đến cùng một đối tượng hay không. ==kiểm tra xem hai đối tượng có cùng giá trị hay không.

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

2

Như John Women'sella đã nói, hầu hết thời gian bạn sẽ sử dụng == và! = Vì mục tiêu của bạn là so sánh các giá trị. Tôi chỉ muốn phân loại những gì bạn sẽ làm trong phần còn lại của thời gian:

Có một và chỉ một ví dụ của noneType, tức là Không có đơn lẻ. Do đó foo == Nonefoo is Nonecó nghĩa là như nhau. Tuy nhiên, isbài kiểm tra nhanh hơn và quy ước Pythonic sẽ được sử dụng foo is None.

Nếu bạn đang làm một số mẫn hoặc mucking về với thu gom rác thải hoặc kiểm tra xem chuỗi tùy chỉnh của mình thực tập tiện ích đang làm việc hay như vậy, sau đó bạn có thể có một use-case cho foobar.

Đúng và Sai cũng là (hiện tại) singletons, nhưng không có trường hợp sử dụng cho foo == Truevà không có trường hợp sử dụng cho foo is True.


2

Hầu hết trong số họ đã trả lời cho điểm. Cũng như một ghi chú bổ sung (dựa trên sự hiểu biết và thử nghiệm của tôi nhưng không phải từ một nguồn tài liệu), tuyên bố

== nếu các đối tượng được gọi bởi các biến bằng nhau

từ câu trả lời trên nên được đọc là

== nếu các đối tượng được tham chiếu bởi các biến bằng nhau và các đối tượng thuộc cùng loại / lớp

. Tôi đi đến kết luận này dựa trên bài kiểm tra dưới đây:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Ở đây nội dung của danh sách và bộ dữ liệu giống nhau nhưng loại / lớp khác nhau.


2

Sự khác biệt của Python giữa is và bằng (==)

Toán tử is có vẻ giống như toán tử đẳng thức nhưng chúng không giống nhau.

Các kiểm tra là nếu cả hai biến chỉ đến cùng một đối tượng trong khi dấu == kiểm tra xem các giá trị cho hai biến có giống nhau không.

Vì vậy, nếu toán tử là trả về True thì đẳng thức chắc chắn là True, nhưng ngược lại có thể đúng hoặc không đúng.

Dưới đây là một ví dụ để chứng minh sự tương đồng và khác biệt.

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

1
Vui lòng chỉ sử dụng dấu ngoặc kép cho văn bản bạn trích dẫn từ một nguồn khác, tại thời điểm đó bạn phải bao gồm phân bổ (xem stackoverflow.com/help/references ). Nếu đây là văn bản của riêng bạn, vui lòng xóa dấu ngoặc kép.
Martijn Pieters

0

Khi những người khác trong bài đăng này trả lời chi tiết câu hỏi, tôi sẽ nhấn mạnh chủ yếu là so sánh giữa is== cho các chuỗi có thể cho kết quả khác nhau và tôi mong các lập trình viên sử dụng chúng một cách cẩn thận.

Để so sánh chuỗi, đảm bảo sử dụng ==thay vì is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Ngoài:

str is hello
str == hello

Nhưng trong ví dụ dưới đây ==issẽ nhận được kết quả khác nhau:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

Ngoài:

str == hello sam

Phần kết luận:

Sử dụng iscẩn thận để so sánh giữa các chuỗi


tại sao "là" "hoạt động như vậy đối với các chuỗi có khoảng trắng?
Akash Gupta

Theo các câu trả lời trước: Có vẻ như python thực hiện lưu vào bộ đệm trên số nguyên và chuỗi nhỏ, điều đó có nghĩa là nó sử dụng cùng một tham chiếu đối tượng cho các lần xuất hiện chuỗi 'hello' trong ảnh chụp mã này, trong khi nó không tạo trước bộ đệm cho 'hello sam' vì nó là tương đối lớn hơn 'xin chào' (nghĩa là nó quản lý các tham chiếu khác nhau của chuỗi 'xin chào sam' và đó là lý do tại sao toán tử 'là' trả về sai trong ví dụ sau) Vui lòng sửa cho tôi nếu tôi sai
Rida Shamasneh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.