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

Python bitarray列表与原地异或操作^=的异常行为探究

Python中bitarray列表与异或操作的行为差异解析

复现代码

ls = [bitarray('0'), bitarray('0')]
ls[0] ^= bitarray('1')
print(ls)
# 输出: [bitarray('1'), bitarray('0')]

ls = [bitarray('0')]*2
ls[0] ^= bitarray('1')
print(ls)
# 输出: [bitarray('1'), bitarray('1')]

ls = [bitarray('0'), bitarray('0')]
ls[0] = ls[0] ^ bitarray('1')
print(ls)
# 输出: [bitarray('1'), bitarray('0')]

疑问解答

  • 疑问1:为什么第二个代码块和第一个结果不同?
    你猜的没错,[bitarray('0')]*2确实是复制引用,而非创建两个独立的bitarray对象。整数无法复现该行为的原因是:整数属于Python的不可变类型,对不可变类型执行操作时,会生成新对象而不修改原对象;但bitarray是可变类型,^=是原地修改操作,会直接改变原对象的内容。

用*2创建列表时,两个元素指向同一个bitarray实例,修改其中一个就会同步影响另一个;而第一个代码块里的[bitarray('0'), bitarray('0')]是生成两个独立的bitarray对象,修改其中一个自然不会波及另一个。

  • 疑问2:为什么ls[0] ^= bitarray('1')和ls[0] = ls[0] ^ bitarray('1')结果不同?
    这两个操作并非等价简写,核心差异在于是否原地修改对象:
    • ^=调用的是bitarray的__ixor__方法,属于原地操作,它直接修改当前列表元素指向的bitarray对象本身,不会改变列表元素的引用关系。
    • ls[0] = ls[0] ^ bitarray('1')中,^调用的是__xor__方法,会生成一个新的bitarray对象,随后将列表第一个元素的引用替换为这个新对象,原对象并未被修改。

所以在第二个代码块的共享引用场景下,^=会修改共享的那个bitarray实例,导致两个列表元素都显示修改后的值;而赋值方式是替换引用,原共享对象保持不变,另一个列表元素仍指向原对象,因此结果和第一个代码块一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:22:04