2017-09-20 17 views

Trả lời

9

Lý do tại sao ví dụ đầu tiên không hoạt động là bởi vì bạn là gọi .index() nhiều lần và sau mỗi lần, các giá trị trong danh sách sẽ thay đổi, vì vậy các chỉ mục được tìm thấy trong mã không đại diện cho vị trí thực tế của các phần tử. Ví dụ thứ hai hoạt động vì bạn đã lưu trữ các chỉ mục đầu tiên trong hai biến và sử dụng cả hai trong trao đổi.

Tổng quan về ví dụ đầu tiên:

lol[lol.index("test")], lol[lol.index("test2")] = lol[lol.index("test2")], lol[lol.index("test")] 

phần đầu tiên: lol[lol.index("test")] cửa hàng 0

phần thứ hai: lol[lol.index("test2")] cửa hàng 1

Thứ ba phần: lol[lol.index("test2")] vẫn cửa hàng 1

Đây là thời điểm nó được interes ting. Phần thứ nhất của ví dụ, lol[lol.index("test")], tìm chỉ mục là test, tuy nhiên, test được gán 1 từ đoạn thứ ba của mã. Do đó, lol[lol.index("test")]1, không phải 0. Do đó, lol[lol.index("test2")] vẫn lưu trữ 1.

+3

Điều này cho thấy ấn tượng sai rằng trong một câu lệnh 'A, B = C, D' thứ tự đánh giá là ** 1. ** A; ** 2. ** B; ** 3. ** C; ** 4. ** A = C; ** 5. ** D; ** 6. ** B = D. Trong khi thứ tự đánh giá phải là ** 1. ** C; ** 2. ** D; ** 3. ** A; ** 4. ** B; ** 5. ** A = C; ** 6. ** B = D – kaza

1

X,Y="test","test2" sẽ được xử lý như X="test";Y="test2"

lol = ["test","test2"] 
lol[lol.index("test")], lol[lol.index("test2")] = lol[lol.index("test2")], lol[lol.index("test")] 

Đầu tiên phía bên tay phải sẽ được đánh giá, vì vậy bạn sẽ có được:

lol[lol.index("test")], lol[lol.index("test2")] = "test2", "test" 

đó sẽ có tác dụng tương tự như các dòng sau đây:

lol[lol.index("test")]="test2" 
# returns 0 
# lol==["test2","test2"] 
lol[lol.index("test2")]="test" 
# returns 0 
+1

Mặc dù rõ ràng là bạn có thể khẳng định rằng RHS được đánh giá trước tiên. Như một số người có thể giả định rằng các câu lệnh được chia trước và sau đó được đánh giá sau. – kaza

+0

@bulbus đồng ý, trên thực tế tôi nghĩ rằng dòng đầu tiên là khá gây hiểu nhầm vì nó ngụ ý thứ tự cho 2 hoạt động này là như nhau, điều đó không đúng tất nhiên –

3

Giải thích

Tất cả đều đi xuống để hiểu chính xác cách hoạt động của evaluation order tại đây, đặc biệt là trường hợp expr3, expr4 = expr1, expr2.

Nếu chúng ta bước qua báo cáo kết quả lol[lol.index("test")], lol[lol.index("test2")] = lol[lol.index("test2")], lol[lol.index("test")] chúng tôi muốn có được một cái gì đó như thế này:

r1=evaluate(expr1) --> "test2" 
r2=evaluate(expr2) --> "test" 
evaluate(expr3)=r1 --> lol[0] = "test2" --> lol = ["test2","test2"] 
evaluate(expr4)=r2 --> lol[0] = "test" --> lol = ["test", "test2"] 

Đoạn khác là tầm thường:

i1 = lol.index("test") 
i2 = lol.index("test2") 
lol[i1], lol[i2] = lol[i2], lol[i1] 

it1) i1 = 0 
it2) i2 = 1 
it3) lol[i1], lol[i2] = "test2", lol[i1] 
it4) lol[i1], lol[i2] = "test2", "test" 
it5) lol[i1] = "test2" 
it6) lol[i2] = "test" 

lựa chọn thay thế oneliner

Something như thế này những người nên làm:

lol = lol[lol.index("test2")], lol[lol.index("test")] 

lol[0], lol[1] = lol[1], lol[0] 

lol[0], lol[1] = lol[lol.index("test2")], lol[lol.index("test")] 

ghi chú aditional

Nếu bạn thực sự muốn biết thêm về cách các chức năng này đang thực sự diễn giải, một cách rất tốt để làm như vậy là bằng cách sử dụng các mô-đun dis, ví dụ:

>>> import dis 
>>> def f(): 
... lst[lst.index(str1)], lst[lst.index(str2)] = lst[lst.index(str2)], lst[lst.index(str1)] 
... 
>>> dis.dis(f) 
    2   0 LOAD_GLOBAL    0 (lst) 
       3 LOAD_GLOBAL    0 (lst) 
       6 LOAD_ATTR    1 (index) 
       9 LOAD_GLOBAL    2 (str2) 
      12 CALL_FUNCTION   1 
      15 BINARY_SUBSCR 
      16 LOAD_GLOBAL    0 (lst) 
      19 LOAD_GLOBAL    0 (lst) 
      22 LOAD_ATTR    1 (index) 
      25 LOAD_GLOBAL    3 (str1) 
      28 CALL_FUNCTION   1 
      31 BINARY_SUBSCR 
      32 ROT_TWO 
      33 LOAD_GLOBAL    0 (lst) 
      36 LOAD_GLOBAL    0 (lst) 
      39 LOAD_ATTR    1 (index) 
      42 LOAD_GLOBAL    3 (str1) 
      45 CALL_FUNCTION   1 
      48 STORE_SUBSCR 
      49 LOAD_GLOBAL    0 (lst) 
      52 LOAD_GLOBAL    0 (lst) 
      55 LOAD_ATTR    1 (index) 
      58 LOAD_GLOBAL    2 (str2) 
      61 CALL_FUNCTION   1 
      64 STORE_SUBSCR 
      65 LOAD_CONST    0 (None) 
      68 RETURN_VALUE 
>>> 
Các vấn đề liên quan