[{"data":1,"prerenderedAt":1139},["ShallowReactive",2],{"blog-\u002Fblog\u002Fpython-mutability-mutable-immutable-types":3},{"id":4,"title":5,"body":6,"description":1125,"difficulty":1126,"extension":1127,"framework":1128,"frameworkSlug":88,"meta":1129,"navigation":160,"order":96,"path":1130,"qaPath":1131,"seo":1132,"stem":1133,"subtopic":1134,"topic":1135,"topicSlug":1136,"updated":1137,"__hash__":1138},"blog\u002Fblog\u002Fpython-mutability-mutable-immutable-types.md","Python Mutability — Mutable vs Immutable Types Explained",{"type":7,"value":8,"toc":1113},"minimark",[9,14,18,22,83,231,248,252,267,329,336,340,354,449,457,461,468,527,533,590,594,614,682,716,720,754,867,876,880,886,936,959,963,993,1068,1079,1083,1109],[10,11,13],"h2",{"id":12},"python-mutability-explained","Python mutability, explained",[15,16,17],"p",{},"Mutability is one of the most consequential ideas in Python. Whether a type can be\nchanged in place determines how assignment behaves, what happens when you pass an object\nto a function, which objects can be dictionary keys, and a whole family of subtle bugs\n(the mutable default argument, shared references, aliasing). This guide makes the model\nconcrete and walks through the traps.",[10,19,21],{"id":20},"mutable-vs-immutable-types","Mutable vs immutable types",[23,24,25,64],"ul",{},[26,27,28,32,33,37,38,37,41,37,44,37,47,50,51,37,54,37,57,37,60,63],"li",{},[29,30,31],"strong",{},"Immutable"," — can never change in place: ",[34,35,36],"code",{},"int",", ",[34,39,40],{},"float",[34,42,43],{},"complex",[34,45,46],{},"bool",[34,48,49],{},"str",",\n",[34,52,53],{},"tuple",[34,55,56],{},"frozenset",[34,58,59],{},"bytes",[34,61,62],{},"None",".",[26,65,66,69,70,37,73,37,76,37,79,82],{},[29,67,68],{},"Mutable"," — can be modified in place: ",[34,71,72],{},"list",[34,74,75],{},"dict",[34,77,78],{},"set",[34,80,81],{},"bytearray",", and most\ncustom objects.",[84,85,90],"pre",{"className":86,"code":87,"language":88,"meta":89,"style":89},"language-python shiki shiki-themes github-light github-dark","s = \"hello\"\nprint(id(s))\ns += \" world\"   # looks like mutation...\nprint(id(s))    # ...but id() changed — a NEW string was created\n\nnums = [1, 2, 3]\nprint(id(nums))\nnums.append(4)  # genuine in-place mutation\nprint(id(nums)) # same id — same object\n","python","",[34,91,92,109,125,140,155,162,189,201,216],{"__ignoreMap":89},[93,94,97,101,105],"span",{"class":95,"line":96},"line",1,[93,98,100],{"class":99},"sVt8B","s ",[93,102,104],{"class":103},"szBVR","=",[93,106,108],{"class":107},"sZZnC"," \"hello\"\n",[93,110,112,116,119,122],{"class":95,"line":111},2,[93,113,115],{"class":114},"sj4cs","print",[93,117,118],{"class":99},"(",[93,120,121],{"class":114},"id",[93,123,124],{"class":99},"(s))\n",[93,126,128,130,133,136],{"class":95,"line":127},3,[93,129,100],{"class":99},[93,131,132],{"class":103},"+=",[93,134,135],{"class":107}," \" world\"",[93,137,139],{"class":138},"sJ8bj","   # looks like mutation...\n",[93,141,143,145,147,149,152],{"class":95,"line":142},4,[93,144,115],{"class":114},[93,146,118],{"class":99},[93,148,121],{"class":114},[93,150,151],{"class":99},"(s))    ",[93,153,154],{"class":138},"# ...but id() changed — a NEW string was created\n",[93,156,158],{"class":95,"line":157},5,[93,159,161],{"emptyLinePlaceholder":160},true,"\n",[93,163,165,168,170,173,176,178,181,183,186],{"class":95,"line":164},6,[93,166,167],{"class":99},"nums ",[93,169,104],{"class":103},[93,171,172],{"class":99}," [",[93,174,175],{"class":114},"1",[93,177,37],{"class":99},[93,179,180],{"class":114},"2",[93,182,37],{"class":99},[93,184,185],{"class":114},"3",[93,187,188],{"class":99},"]\n",[93,190,192,194,196,198],{"class":95,"line":191},7,[93,193,115],{"class":114},[93,195,118],{"class":99},[93,197,121],{"class":114},[93,199,200],{"class":99},"(nums))\n",[93,202,204,207,210,213],{"class":95,"line":203},8,[93,205,206],{"class":99},"nums.append(",[93,208,209],{"class":114},"4",[93,211,212],{"class":99},")  ",[93,214,215],{"class":138},"# genuine in-place mutation\n",[93,217,219,221,223,225,228],{"class":95,"line":218},9,[93,220,115],{"class":114},[93,222,118],{"class":99},[93,224,121],{"class":114},[93,226,227],{"class":99},"(nums)) ",[93,229,230],{"class":138},"# same id — same object\n",[15,232,233,236,237,239,240,243,244,247],{},[34,234,235],{},"id(obj)"," returns an object's identity (its address in CPython); two names with the same\n",[34,238,121],{}," are the ",[29,241,242],{},"same object",". Immutable objects are also ",[29,245,246],{},"hashable",", which is why they\ncan be dict keys and set members.",[10,249,251],{"id":250},"names-objects-and-aliasing","Names, objects, and aliasing",[15,253,254,255,258,259,262,263,266],{},"In Python, variables are ",[29,256,257],{},"names bound to objects",", not boxes holding values. Assigning\none name to another makes both point at the ",[29,260,261],{},"same"," object — an alias. Mutating through\none alias is visible through the other; ",[29,264,265],{},"rebinding"," a name is not.",[84,268,270],{"className":86,"code":269,"language":88,"meta":89,"style":89},"a = [1, 2]\nb = a\na.append(3)   # mutate -> b sees it; b == [1, 2, 3]\na = [9]       # rebind -> b unchanged; b == [1, 2, 3]\n",[34,271,272,289,299,312],{"__ignoreMap":89},[93,273,274,277,279,281,283,285,287],{"class":95,"line":96},[93,275,276],{"class":99},"a ",[93,278,104],{"class":103},[93,280,172],{"class":99},[93,282,175],{"class":114},[93,284,37],{"class":99},[93,286,180],{"class":114},[93,288,188],{"class":99},[93,290,291,294,296],{"class":95,"line":111},[93,292,293],{"class":99},"b ",[93,295,104],{"class":103},[93,297,298],{"class":99}," a\n",[93,300,301,304,306,309],{"class":95,"line":127},[93,302,303],{"class":99},"a.append(",[93,305,185],{"class":114},[93,307,308],{"class":99},")   ",[93,310,311],{"class":138},"# mutate -> b sees it; b == [1, 2, 3]\n",[93,313,314,316,318,320,323,326],{"class":95,"line":142},[93,315,276],{"class":99},[93,317,104],{"class":103},[93,319,172],{"class":99},[93,321,322],{"class":114},"9",[93,324,325],{"class":99},"]       ",[93,327,328],{"class":138},"# rebind -> b unchanged; b == [1, 2, 3]\n",[15,330,331,332,335],{},"This distinction — ",[29,333,334],{},"mutate vs rebind"," — explains most \"why did my other variable\nchange?\" confusion.",[10,337,339],{"id":338},"passing-arguments-pass-by-object-reference","Passing arguments: pass-by-object-reference",[15,341,342,343,346,347,350,351,353],{},"Python is neither pure pass-by-value nor pass-by-reference; it's ",[29,344,345],{},"pass-by-object-\nreference"," (\"pass by assignment\"). A function receives a reference to the same object,\nso it can ",[29,348,349],{},"mutate"," a mutable argument in place, but ",[29,352,265],{}," the parameter doesn't\naffect the caller.",[84,355,357],{"className":86,"code":356,"language":88,"meta":89,"style":89},"def mutate(lst): lst.append(4)   # caller sees this\ndef rebind(lst): lst = [0]       # caller does NOT see this\n\ndata = [1, 2, 3]\nmutate(data); print(data)  # [1, 2, 3, 4]\nrebind(data); print(data)  # [1, 2, 3, 4]\n",[34,358,359,378,400,404,425,438],{"__ignoreMap":89},[93,360,361,364,368,371,373,375],{"class":95,"line":96},[93,362,363],{"class":103},"def",[93,365,367],{"class":366},"sScJk"," mutate",[93,369,370],{"class":99},"(lst): lst.append(",[93,372,209],{"class":114},[93,374,308],{"class":99},[93,376,377],{"class":138},"# caller sees this\n",[93,379,380,382,385,388,390,392,395,397],{"class":95,"line":111},[93,381,363],{"class":103},[93,383,384],{"class":366}," rebind",[93,386,387],{"class":99},"(lst): lst ",[93,389,104],{"class":103},[93,391,172],{"class":99},[93,393,394],{"class":114},"0",[93,396,325],{"class":99},[93,398,399],{"class":138},"# caller does NOT see this\n",[93,401,402],{"class":95,"line":127},[93,403,161],{"emptyLinePlaceholder":160},[93,405,406,409,411,413,415,417,419,421,423],{"class":95,"line":142},[93,407,408],{"class":99},"data ",[93,410,104],{"class":103},[93,412,172],{"class":99},[93,414,175],{"class":114},[93,416,37],{"class":99},[93,418,180],{"class":114},[93,420,37],{"class":99},[93,422,185],{"class":114},[93,424,188],{"class":99},[93,426,427,430,432,435],{"class":95,"line":157},[93,428,429],{"class":99},"mutate(data); ",[93,431,115],{"class":114},[93,433,434],{"class":99},"(data)  ",[93,436,437],{"class":138},"# [1, 2, 3, 4]\n",[93,439,440,443,445,447],{"class":95,"line":164},[93,441,442],{"class":99},"rebind(data); ",[93,444,115],{"class":114},[93,446,434],{"class":99},[93,448,437],{"class":138},[15,450,451,452,456],{},"Immutable arguments (ints, strings, tuples) can't be mutated, so they ",[453,454,455],"em",{},"appear","\npass-by-value.",[10,458,460],{"id":459},"the-mutable-default-argument-trap","The mutable default argument trap",[15,462,463,464,467],{},"A default argument is evaluated ",[29,465,466],{},"once, when the function is defined"," — not on each\ncall. So a mutable default is shared across all calls, accumulating state.",[84,469,471],{"className":86,"code":470,"language":88,"meta":89,"style":89},"def add(item, bucket=[]):  # same list every call\n    bucket.append(item)\n    return bucket\nadd(1)  # [1]\nadd(2)  # [1, 2]  \u003C- surprise!\n",[34,472,473,491,496,504,516],{"__ignoreMap":89},[93,474,475,477,480,483,485,488],{"class":95,"line":96},[93,476,363],{"class":103},[93,478,479],{"class":366}," add",[93,481,482],{"class":99},"(item, bucket",[93,484,104],{"class":103},[93,486,487],{"class":99},"[]):  ",[93,489,490],{"class":138},"# same list every call\n",[93,492,493],{"class":95,"line":111},[93,494,495],{"class":99},"    bucket.append(item)\n",[93,497,498,501],{"class":95,"line":127},[93,499,500],{"class":103},"    return",[93,502,503],{"class":99}," bucket\n",[93,505,506,509,511,513],{"class":95,"line":142},[93,507,508],{"class":99},"add(",[93,510,175],{"class":114},[93,512,212],{"class":99},[93,514,515],{"class":138},"# [1]\n",[93,517,518,520,522,524],{"class":95,"line":157},[93,519,508],{"class":99},[93,521,180],{"class":114},[93,523,212],{"class":99},[93,525,526],{"class":138},"# [1, 2]  \u003C- surprise!\n",[15,528,529,530,532],{},"The fix is the ",[34,531,62],{}," sentinel — create a fresh object inside the body:",[84,534,536],{"className":86,"code":535,"language":88,"meta":89,"style":89},"def add(item, bucket=None):\n    if bucket is None:\n        bucket = []\n    bucket.append(item)\n    return bucket\n",[34,537,538,553,570,580,584],{"__ignoreMap":89},[93,539,540,542,544,546,548,550],{"class":95,"line":96},[93,541,363],{"class":103},[93,543,479],{"class":366},[93,545,482],{"class":99},[93,547,104],{"class":103},[93,549,62],{"class":114},[93,551,552],{"class":99},"):\n",[93,554,555,558,561,564,567],{"class":95,"line":111},[93,556,557],{"class":103},"    if",[93,559,560],{"class":99}," bucket ",[93,562,563],{"class":103},"is",[93,565,566],{"class":114}," None",[93,568,569],{"class":99},":\n",[93,571,572,575,577],{"class":95,"line":127},[93,573,574],{"class":99},"        bucket ",[93,576,104],{"class":103},[93,578,579],{"class":99}," []\n",[93,581,582],{"class":95,"line":142},[93,583,495],{"class":99},[93,585,586,588],{"class":95,"line":157},[93,587,500],{"class":103},[93,589,503],{"class":99},[10,591,593],{"id":592},"is-vs","is vs ==",[15,595,596,599,600,603,604,607,608,599,610,613],{},[34,597,598],{},"=="," tests ",[29,601,602],{},"value equality"," (calls ",[34,605,606],{},"__eq__","); ",[34,609,563],{},[29,611,612],{},"identity"," (same object).\nThey often agree, but not always.",[84,615,617],{"className":86,"code":616,"language":88,"meta":89,"style":89},"a = [1, 2, 3]\nb = [1, 2, 3]\na == b   # True  — equal contents\na is b   # False — distinct objects\n",[34,618,619,639,659,671],{"__ignoreMap":89},[93,620,621,623,625,627,629,631,633,635,637],{"class":95,"line":96},[93,622,276],{"class":99},[93,624,104],{"class":103},[93,626,172],{"class":99},[93,628,175],{"class":114},[93,630,37],{"class":99},[93,632,180],{"class":114},[93,634,37],{"class":99},[93,636,185],{"class":114},[93,638,188],{"class":99},[93,640,641,643,645,647,649,651,653,655,657],{"class":95,"line":111},[93,642,293],{"class":99},[93,644,104],{"class":103},[93,646,172],{"class":99},[93,648,175],{"class":114},[93,650,37],{"class":99},[93,652,180],{"class":114},[93,654,37],{"class":99},[93,656,185],{"class":114},[93,658,188],{"class":99},[93,660,661,663,665,668],{"class":95,"line":127},[93,662,276],{"class":99},[93,664,598],{"class":103},[93,666,667],{"class":99}," b   ",[93,669,670],{"class":138},"# True  — equal contents\n",[93,672,673,675,677,679],{"class":95,"line":142},[93,674,276],{"class":99},[93,676,563],{"class":103},[93,678,667],{"class":99},[93,680,681],{"class":138},"# False — distinct objects\n",[15,683,684,690,691,37,693,37,696,699,700,702,705,706,709,710,713,714,63],{},[29,685,686,687,689],{},"Use ",[34,688,563],{}," only for singletons"," — ",[34,692,62],{},[34,694,695],{},"True",[34,697,698],{},"False",". Don't use it for numbers or\nstrings: CPython caches small integers (−5 to 256) and interns some strings, so ",[34,701,563],{},[453,703,704],{},"coincidentally"," works for them and then fails unpredictably outside those ranges. PEP 8\nspecifically recommends ",[34,707,708],{},"x is None",", partly because ",[34,711,712],{},"== None"," can be overridden by a\ncustom ",[34,715,606],{},[10,717,719],{"id":718},"copying-shallow-vs-deep","Copying: shallow vs deep",[15,721,722,723,726,727,37,730,37,733,37,736,37,739,742,743,746,747,726,750,753],{},"A ",[29,724,725],{},"shallow copy"," (",[34,728,729],{},"copy.copy",[34,731,732],{},"list(x)",[34,734,735],{},"x[:]",[34,737,738],{},"dict(x)",[34,740,741],{},"{**d}",") duplicates the\nouter container but ",[29,744,745],{},"shares"," the nested objects. A ",[29,748,749],{},"deep copy",[34,751,752],{},"copy.deepcopy",")\nrecursively copies everything.",[84,755,757],{"className":86,"code":756,"language":88,"meta":89,"style":89},"import copy\noriginal = [[1, 2], [3, 4]]\nshallow = copy.copy(original)\nshallow[0].append(99)\nprint(original)   # [[1, 2, 99], [3, 4]]  \u003C- inner list shared!\n\ndeep = copy.deepcopy(original)\ndeep[0].append(99)\nprint(original)   # unchanged — fully independent\n",[34,758,759,767,795,805,821,831,835,845,858],{"__ignoreMap":89},[93,760,761,764],{"class":95,"line":96},[93,762,763],{"class":103},"import",[93,765,766],{"class":99}," copy\n",[93,768,769,772,774,777,779,781,783,786,788,790,792],{"class":95,"line":111},[93,770,771],{"class":99},"original ",[93,773,104],{"class":103},[93,775,776],{"class":99}," [[",[93,778,175],{"class":114},[93,780,37],{"class":99},[93,782,180],{"class":114},[93,784,785],{"class":99},"], [",[93,787,185],{"class":114},[93,789,37],{"class":99},[93,791,209],{"class":114},[93,793,794],{"class":99},"]]\n",[93,796,797,800,802],{"class":95,"line":127},[93,798,799],{"class":99},"shallow ",[93,801,104],{"class":103},[93,803,804],{"class":99}," copy.copy(original)\n",[93,806,807,810,812,815,818],{"class":95,"line":142},[93,808,809],{"class":99},"shallow[",[93,811,394],{"class":114},[93,813,814],{"class":99},"].append(",[93,816,817],{"class":114},"99",[93,819,820],{"class":99},")\n",[93,822,823,825,828],{"class":95,"line":157},[93,824,115],{"class":114},[93,826,827],{"class":99},"(original)   ",[93,829,830],{"class":138},"# [[1, 2, 99], [3, 4]]  \u003C- inner list shared!\n",[93,832,833],{"class":95,"line":164},[93,834,161],{"emptyLinePlaceholder":160},[93,836,837,840,842],{"class":95,"line":191},[93,838,839],{"class":99},"deep ",[93,841,104],{"class":103},[93,843,844],{"class":99}," copy.deepcopy(original)\n",[93,846,847,850,852,854,856],{"class":95,"line":203},[93,848,849],{"class":99},"deep[",[93,851,394],{"class":114},[93,853,814],{"class":99},[93,855,817],{"class":114},[93,857,820],{"class":99},[93,859,860,862,864],{"class":95,"line":218},[93,861,115],{"class":114},[93,863,827],{"class":99},[93,865,866],{"class":138},"# unchanged — fully independent\n",[15,868,869,872,873,875],{},[34,870,871],{},"deepcopy"," even handles circular references safely via an internal memo. Use a shallow\ncopy when elements are immutable (or sharing is fine); use ",[34,874,871],{}," for nested mutables\nyou'll modify independently.",[10,877,879],{"id":878},"hashability-why-a-list-cant-be-a-dict-key","Hashability: why a list can't be a dict key",[15,881,882,883,885],{},"Dictionary keys and set members must be ",[29,884,246],{},", which requires the hash to stay\nconstant for the object's lifetime — i.e. effectively immutable. Lists, dicts, and sets\nare mutable and unhashable.",[84,887,889],{"className":86,"code":888,"language":88,"meta":89,"style":89},"{(1, 2): 'ok'}    # tuple key\n{[1, 2]: 'no'}    # TypeError: unhashable type: 'list'\n",[34,890,891,914],{"__ignoreMap":89},[93,892,893,896,898,900,902,905,908,911],{"class":95,"line":96},[93,894,895],{"class":99},"{(",[93,897,175],{"class":114},[93,899,37],{"class":99},[93,901,180],{"class":114},[93,903,904],{"class":99},"): ",[93,906,907],{"class":107},"'ok'",[93,909,910],{"class":99},"}    ",[93,912,913],{"class":138},"# tuple key\n",[93,915,916,919,921,923,925,928,931,933],{"class":95,"line":111},[93,917,918],{"class":99},"{[",[93,920,175],{"class":114},[93,922,37],{"class":99},[93,924,180],{"class":114},[93,926,927],{"class":99},"]: ",[93,929,930],{"class":107},"'no'",[93,932,910],{"class":99},[93,934,935],{"class":138},"# TypeError: unhashable type: 'list'\n",[15,937,938,939,941,942,944,945,947,948,951,952,955,956,958],{},"If a key could mutate after insertion, its hash would change and you'd never find it\nagain. Use a ",[29,940,53],{}," instead of a list, a ",[29,943,56],{}," instead of a set. For custom\nclasses, implement ",[34,946,606],{}," and ",[34,949,950],{},"__hash__"," ",[29,953,954],{},"consistently"," (equal objects -> equal\nhashes), hashing only on fields that never change; defining ",[34,957,606],{}," alone makes a class\nunhashable.",[10,960,962],{"id":961},"two-more-traps","Two more traps",[15,964,965,966,690,969,972,973,976,977,980,981,984,985,988,989,992],{},"A tuple is immutable, but its ",[29,967,968],{},"contents can be mutable",[34,970,971],{},"t[0].append(x)"," works if\n",[34,974,975],{},"t[0]"," is a list (and ",[34,978,979],{},"t[0] += [x]"," both mutates the list ",[453,982,983],{},"and"," raises a ",[34,986,987],{},"TypeError",").\nAnd list multiplication copies ",[29,990,991],{},"references",":",[84,994,996],{"className":86,"code":995,"language":88,"meta":89,"style":89},"grid = [[]] * 3\ngrid[0].append(1)\nprint(grid)            # [[1], [1], [1]] — all share one list!\ngrid = [[] for _ in range(3)]  # three distinct lists\n",[34,997,998,1014,1027,1037],{"__ignoreMap":89},[93,999,1000,1003,1005,1008,1011],{"class":95,"line":96},[93,1001,1002],{"class":99},"grid ",[93,1004,104],{"class":103},[93,1006,1007],{"class":99}," [[]] ",[93,1009,1010],{"class":103},"*",[93,1012,1013],{"class":114}," 3\n",[93,1015,1016,1019,1021,1023,1025],{"class":95,"line":111},[93,1017,1018],{"class":99},"grid[",[93,1020,394],{"class":114},[93,1022,814],{"class":99},[93,1024,175],{"class":114},[93,1026,820],{"class":99},[93,1028,1029,1031,1034],{"class":95,"line":127},[93,1030,115],{"class":114},[93,1032,1033],{"class":99},"(grid)            ",[93,1035,1036],{"class":138},"# [[1], [1], [1]] — all share one list!\n",[93,1038,1039,1041,1043,1046,1049,1052,1055,1058,1060,1062,1065],{"class":95,"line":142},[93,1040,1002],{"class":99},[93,1042,104],{"class":103},[93,1044,1045],{"class":99}," [[] ",[93,1047,1048],{"class":103},"for",[93,1050,1051],{"class":99}," _ ",[93,1053,1054],{"class":103},"in",[93,1056,1057],{"class":114}," range",[93,1059,118],{"class":99},[93,1061,185],{"class":114},[93,1063,1064],{"class":99},")]  ",[93,1066,1067],{"class":138},"# three distinct lists\n",[15,1069,1070,1071,1074,1075,1078],{},"Also avoid modifying a list while iterating over it (it skips elements); build a new list\nwith a comprehension instead. And remember ",[34,1072,1073],{},"del name"," unbinds the ",[453,1076,1077],{},"name",", not necessarily\nthe object (which lives until its refcount hits zero).",[10,1080,1082],{"id":1081},"recap","Recap",[15,1084,1085,1086,1088,1089,1092,1093,1096,1097,1099,1100,1102,1103,1105,1106,1108],{},"Python variables are ",[29,1087,257],{},"; whether a type is ",[29,1090,1091],{},"mutable"," decides\neverything downstream. Aliases share ",[29,1094,1095],{},"mutations"," but not ",[29,1098,265],{},"; arguments are\npassed by object reference, so functions can mutate but not rebind. Use the ",[34,1101,62],{},"\nsentinel for mutable defaults, ",[34,1104,563],{}," only for singletons, and ",[34,1107,871],{}," for independent\nnested copies. Immutable types are hashable (dict keys, set members); mutable ones aren't.\nKeep the mutate-vs-rebind distinction in mind and Python's reference semantics stop\nsurprising you.",[1110,1111,1112],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":89,"searchDepth":111,"depth":111,"links":1114},[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124],{"id":12,"depth":111,"text":13},{"id":20,"depth":111,"text":21},{"id":250,"depth":111,"text":251},{"id":338,"depth":111,"text":339},{"id":459,"depth":111,"text":460},{"id":592,"depth":111,"text":593},{"id":718,"depth":111,"text":719},{"id":878,"depth":111,"text":879},{"id":961,"depth":111,"text":962},{"id":1081,"depth":111,"text":1082},"Python interview questions on mutable vs immutable types, the mutable default argument trap, is vs ==, and shallow vs deep copy.","medium","md","Python",{},"\u002Fblog\u002Fpython-mutability-mutable-immutable-types","\u002Fpython\u002Ffundamentals\u002Fmutability",{"title":5,"description":1125},"blog\u002Fpython-mutability-mutable-immutable-types","Mutability & Data Types","Fundamentals","fundamentals","2026-06-17","q2h-vh1uDpyFua2jg4JWAUtaSlg21x4-Pwm4yI0GJoA",1781808673081]