python-3.x - 为什么我的数组的元素被覆盖?
问题描述
我在 Python 中编写了一个简单的函数,旨在通过在其中一个数组中交换最多一对元素来从两个元素a
和中找到一个。b
这是我的功能:
def areSimilar(a, b):
test = 0
for i in range(len(b)):
for j in range(len(b)):
b2 = b
b2[i] = b[j]
b2[j] = b[i]
if a == b2:
test = 1
return(test==1)
问题是,在检查b
时,即使我实际上没有执行任何计算,它也发生了变化b
——发生了什么事!!??
解决方案
(已编辑:为了更好地解决第二点)
您的代码有两个问题:
- 当您这样做时,
b2 = b
只会创建对基础对象的另一个引用。如果b
是可变的,对 的任何更改b2
也将反映在b
其中。 - 当一次交换就足够时,不需要进一步测试,但如果你继续循环测试将再次成功
i
并j
交换,所以test
条件要么永远不会命中,要么(至少 - 取决于重复的数量)两次。虽然这不会导致错误的结果,但通常会被视为逻辑错误。
要修复您的代码,您只需创建一个b
. 假设您所说的 Python 数组实际上是指 Pythonlist
的一种方法,那就是list
每次都通过替换b2 = b
为b2 = list(b)
. 一种更有效的方法是对b
自身执行交换(并交换回):
def are_similar(a, b):
for i in range(len(b)):
for j in range(len(b)):
b[i], b[j] = b[j], b[i]
if a == b:
b[i], b[j] = b[j], b[i] # swap back
return True
else:
b[i], b[j] = b[j], b[i] # swap back
return False
print(are_similar([1, 1, 2, 3], [1, 2, 1, 3]))
# True
print(are_similar([1, 1, 2, 3], [3, 2, 1, 1]))
# False
相比之下,您可以看到基于复制的方法是多么低效(虽然正确):
def are_similar2(a, b):
for i in range(len(b)):
for j in range(len(b)):
b2 = list(b)
b2[i] = b[j]
b2[j] = b[i]
if a == b2:
return True
return False
print(are_similar2([1, 1, 2, 3], [1, 2, 1, 3]))
# True
print(are_similar2([1, 1, 2, 3], [3, 2, 1, 1]))
# False
即使在相对较小的输入上,时间也要差得多:
a = [1, 1, 2, 3] + list(range(100))
b = [1, 2, 1, 3] + list(range(100))
%timeit are_similar(a, b)
# 10000 loops, best of 3: 22.9 µs per loop
%timeit are_similar2(a, b)
# 10000 loops, best of 3: 73.9 µs per loop
推荐阅读
- laravel - Laravel - 未定义的前缀路由
- nginx - Websocket的Nginx超时
- android - DialogFragment:创建片段时仅显示一次动画
- matlab - 查找 Matlab 警告消息 ID 的最简单方法是什么?
- javascript - XLS 文件已打开但未显示正确的数据
- node.js - 无法使用猫鼬在nodejs中创建多条记录
- python - 根据键列合并 3 个 pandas
- java - 自 Spring Boot 升级以来,结合 @ConditionalOnMissingBean 定义 Bean 不起作用
- python - Luminoth 需要 TensorFlow >= 1.5 安装 (Windows 8.1)
- quickfix - 是什么导致 QuickFIX/J 中的“断开连接:遇到 END_OF_STREAM”会话消息?