[英]What is the most 'pythonic' way to logically combine a list of booleans?
[英]Is there a more pythonic way to convert a list of booleans to an integer?
我覺得不得不問這個問題很愚蠢,但我的 memory 避開了更好的選擇。 spring 想到的兩種方法:
第一的:
def f1(v):
return sum(2**i for i,va in enumerate(v) if va)
>>> f1([True, False, True])
5
第二:
def f2(v):
return int('0b' + "".join(str(int(va)) for va in v),2)
>>> f2([True, False, True])
5
我覺得 f1 幾乎是笨拙的 Pythonic,而 f2 顯然太丑了,因為我在多種數據類型之間跳躍。 也許是我的年齡……?
使用左移比提高功率稍快(至少在我的機器上)。 使用按位運算可以鼓勵代碼讀者從二進制數據的角度進行思考。
>>> sum(v << i for i, v in enumerate([True, False, True]))
5
只是為了對比,如果您正在編寫 python 就像您正在編寫類似 c 之類的東西,那么您可以這樣做。
def f(l):
output = 0
for i in range(len(l)):
output |= l[i] << i
return output
在算術運算中使用布爾值(還有 lambda 函數)是非常 Pythonic 的:
lst = [True, False, True]
func = lambda x: sum(2 ** num * i for num, i in enumerate(x))
print(func(lst))
# 5
這是我想出的另一種 hacky 方式:
def f1(v):
return int(''.join(str(int(b)) for b in v), 2)
例子:
>>> def f1(v):
... return int(''.join(str(int(b)) for b in v), 2)
...
>>> f1([True, False, True])
5
>>>
另一個使用map
的相同示例(在我看來更具可讀性):
def f1(v):
return int(''.join(map(str, map(int, v))), 2)
numpy
版本可能是
import numpy as np
m = [True, False, True]
print(np.sum(2**np.nonzero(m)[0]))
# 5
作為 function:
def func(arr, p):
return np.sum(np.power(p, np.nonzero(arr)[0]))
print(func([True, False, True], 2))
# 5
它的解決方案更嚴格,但計算效率很高
>>> import numpy as np
>>> predefined_bytes = 2**(np.arange(32))
>>> predefined_bytes
array([ 1, 2, 4, 8, 16,
32, 64, 128, 256, 512,
1024, 2048, 4096, 8192, 16384,
32768, 65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608, 16777216,
33554432, 67108864, 134217728, 268435456, 536870912,
1073741824, 2147483648])
def binary2decimal(bits,predefined_bytes):
bits = np.array(bits)
return np.sum(bits*predefined_bytes[:bits.shape[0]])
>>> binary2decimal([1,1,1,1,1,1,1,1],predefined_bytes)
255
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.