Pan*_*tch 1 python list nested-lists
假设我有一个矩阵:
[[1, 1, 1, 0, 0,], [0, 1, 0, 1], [1, 0, 1]]
Run Code Online (Sandbox Code Playgroud)
我希望它改为:
[[0, 0, 0, 1, 1,], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
什么可能是处理这种情况的最快方法?
目前,我在另一个for循环中使用for循环,如下所示,这显然太慢了.
for my_row in my_mat:
for my_val in my_row:
my_val = 1 if my_val == 0 else 0
Run Code Online (Sandbox Code Playgroud)
cs9*_*s95 10
我不认为它很慢,但它不是最快的.以下是一些更快的替代方案.
选项1
只需从列表推导中的每个值中减去一个.
>>> [[1 - j for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
这消除了if检查的需要.虽然,这只有在你有一个0/1的列表并且你只想翻转这些值时才有意义.
列表推导的好处是它们能够比循环更快地执行,因为它们已经过优化.
选项2
@trincot建议的另一个替代方案涉及1的XOR运算.
>>> [[j ^ 1 for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
XOR操作通常很快,因此如果您的正值超过1,则这是一个很好的选择.
选项3
@DYZ建议的第三个选项not用于反转这些值 -
>>> [[int(not j) for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
请注意,此南瓜为1.非零值not的整数转换为真理/ falsey值,以及随后int转换False到0,或True到1.
性能
一,设置 -
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
Run Code Online (Sandbox Code Playgroud)
接下来,if表现 -
>>> [[1 - j for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
>>> [[j ^ 1 for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
>>> [[int(not j) for j in i] for i in lst]
[[0, 0, 0, 1, 1], [1, 0, 1, 0], [0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)
最快的"算法"是让你的矩阵不受影响.请记住,在一个单独的标志中,您读取(或写入)的每个值都必须被反转.完成.
但是如果你在物理上需要反转矩阵中的每个值,那么只有一个"算法" - 你已经发现的那个.其余的不是"算法",而是关于"算法"的最有效实施.