You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python怪异特性:二维列表与切片赋值异常及其他案例征集

Python's Surprising Quirks: Explained + Additional Gotchas

Let's break down the two confusing behaviors you encountered, plus dive into other common Python gotchas that trip up even experienced developers.

Quirk 1: The Shared Sublist Trap with [[0]*5]*5

You wrote this code expecting a 5x5 list where only the middle element changes:

x = [[0]*5]*5
x[2][2] = 2

Instead, every sublist gets the same 2 in the third position. Here's why:

  • [0]*5 creates a single list object with five zeros.
  • When you multiply that list by 5 (*5), you're not creating five new lists—you're creating five references to the same list object. So all five sublists point to the exact same place in memory.
  • Modifying any sublist (like x[2][2] = 2) changes that shared underlying list, which reflects in all references.

The Fix

Use a list comprehension to create a new list for each row:

x = [[0]*5 for _ in range(5)]
x[2][2] = 2
# Now only the third sublist has the 2, as expected

The comprehension runs [0]*5 five separate times, generating a new list each time instead of reusing references.

Quirk 2: Why x[:][4] = 4 Doesn't Change the Original List

You assumed x[:] is equivalent to x itself, but that's not quite right:

  • x[:] creates a shallow copy of the original list. It's a new list object that contains references to the same elements as x.
  • So when you do x[:][4] = 4, you're modifying the 5th element of this copy—not the original x. The original list remains untouched because you never assigned anything to it directly.

The Fix

If you want to modify the 5th element of the original list, skip the slice and do this directly:

x[4] = 4

More Python Quirks to Watch Out For

Here are other unexpected behaviors that often catch people off guard:

  • Mutable Default Parameters:

    def add_item(item, lst=[]):
        lst.append(item)
        return lst
    
    print(add_item(1))  # Output: [1]
    print(add_item(2))  # Output: [1, 2] (not [2]!)
    

    Default arguments are initialized once when the function is defined, not every time it's called. So lst reuses the same list across calls. Fix this by using lst=None and initializing inside the function:

    def add_item(item, lst=None):
        if lst is None:
            lst = []
        lst.append(item)
        return lst
    
  • Integer Caching:
    Python caches small integers (-5 to 256) to save memory. This means:

    a = 256
    b = 256
    print(a is b)  # True (same object)
    
    a = 257
    b = 257
    print(a is b)  # False (different objects in interactive mode; may be True in scripts due to compiler optimization)
    

    Use == to compare values, is to check if two variables point to the same object.

  • Booleans Are Integer Subclasses:
    True and False are just aliases for 1 and 0:

    print(True == 1)  # True
    print(False == 0)  # True
    print(1 + True)  # 2
    print([True, False][1])  # False (same as accessing index 1 of [1, 0])
    
  • += vs + for Mutable Objects:
    For lists, += modifies the list in-place, while + creates a new list:

    a = [1]
    b = a
    a += [2]
    print(b)  # [1, 2] (b references the same modified list)
    
    a = [1]
    b = a
    a = a + [2]
    print(b)  # [1] (a now points to a new list, b stays with the original)
    
  • String Literal vs Dynamic String:
    String literals that are identical are often cached, but dynamically created strings aren't:

    print("hello" is "hello")  # True (same cached object)
    print("hel" + "lo" is "hello")  # True (compiler merges literals)
    print(str(123) is "123")  # False (dynamic string, new object)
    

内容的提问来源于stack exchange,提问作者nagexiucai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:43:44