在二维列表中交换 0 和 1 的最快方法

Fastest way of interchanging 0s and 1s in a 2D list

假设我有一个矩阵:

[[1, 1, 1, 0, 0,], [0, 1, 0, 1], [1, 0, 1]]

我想将其更改为:

[[0, 0, 0, 1, 1,], [1, 0, 1, 0], [0, 1, 0]]

处理这种情况最快的方法是什么?

目前,我在另一个for循环中使用for循环,如下所示,这显然太慢了。

for my_row in my_mat:
   for my_val in my_row:
      my_val = 1 if my_val == 0 else 0

我不认为它很慢,但它不是最快的。这里有一些更快的选择。

减法(超级简单)

>>> [[1 - j for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]

这消除了 if 检查的需要。虽然,这只有在您有一个 0/​​1 列表并且您只想翻转这些值时才有意义。


异或位翻转

>>> [[j ^ 1 for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]

XOR 运算通常很快,因此如果您的正值超过 1,这是一个很好的选择。


not反转

>>> [[int(not j) for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]

请注意,这会将非零值压缩为 1。not 将整数转换为 truthy/falsy 值,随后的 intFalse 转换为 0,或 True1


如果您对此处建议的所有方法的性能感兴趣,

lst = np.random.choice(2, (1000, 1000)).tolist()

%timeit [[int(not j) for j in i] for i in lst]
%timeit [[j ^ 1 for j in i] for i in lst]
%timeit [[1 - j for j in i] for i in lst]

10 loops, best of 3: 175 ms per loop
10 loops, best of 3: 89.8 ms per loop
10 loops, best of 3: 61.1 ms per loop

最快的 "algo" 是保持矩阵不变。请记住,在一个单独的标志中,您读取(或写入)的每个值都必须反转。完成。

但是如果您实际上需要反转矩阵中的每个值,那么只有一个 "algo" - 您已经发现的那个。剩下的不是关于 "algo",而是关于 "algo".

的最有效的 实现