bool-hybrid-array 9.10.9__py3-none-any.whl → 9.10.21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bool_hybrid_array/__init__.py +7 -4
- bool_hybrid_array/__main__.py +17 -0
- bool_hybrid_array/core.py +874 -856
- bool_hybrid_array/int_array/__init__.py +203 -0
- bool_hybrid_array//321/207/320/267/320/250/321/205/320/277/320/226.md +2 -0
- {bool_hybrid_array-9.10.9.dist-info → bool_hybrid_array-9.10.21.dist-info}/METADATA +47 -7
- bool_hybrid_array-9.10.21.dist-info/RECORD +10 -0
- bool_hybrid_array-9.10.9.dist-info/RECORD +0 -8
- {bool_hybrid_array-9.10.9.dist-info → bool_hybrid_array-9.10.21.dist-info}/WHEEL +0 -0
- {bool_hybrid_array-9.10.9.dist-info → bool_hybrid_array-9.10.21.dist-info}/licenses/LICENSE +0 -0
- {bool_hybrid_array-9.10.9.dist-info → bool_hybrid_array-9.10.21.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from ..core import *
|
|
3
|
+
import builtins
|
|
4
|
+
|
|
5
|
+
class IntBitTag(BHA_bool, metaclass=ResurrectMeta):
|
|
6
|
+
def __str__(self):
|
|
7
|
+
return "'-1'" if (hasattr(self, 'is_sign_bit') and self.is_sign_bit and self) else "'1'" if self else "'0'"
|
|
8
|
+
__repr__ = __str__
|
|
9
|
+
__del__ = lambda self:self
|
|
10
|
+
class IntHybridArray(BoolHybridArray):
|
|
11
|
+
def __init__(self, int_array: list[int], bit_length: int = 8):
|
|
12
|
+
self.bit_length = bit_length
|
|
13
|
+
bool_data = []
|
|
14
|
+
max_required_bits = 1
|
|
15
|
+
for num in int_array:
|
|
16
|
+
if num == 0:
|
|
17
|
+
required_bits = 1
|
|
18
|
+
else:
|
|
19
|
+
abs_num = abs(num)
|
|
20
|
+
num_bits_needed = abs_num.bit_length()
|
|
21
|
+
required_bits = 1 + num_bits_needed
|
|
22
|
+
if required_bits > max_required_bits:
|
|
23
|
+
max_required_bits = required_bits
|
|
24
|
+
self.bit_length = max_required_bits
|
|
25
|
+
for num in int_array:
|
|
26
|
+
if num >= 0:
|
|
27
|
+
sign_bit = False
|
|
28
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
29
|
+
else:
|
|
30
|
+
sign_bit = True
|
|
31
|
+
abs_num = abs(num)
|
|
32
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
33
|
+
carry = 1
|
|
34
|
+
for j in range(len(num_bits)):
|
|
35
|
+
if carry:
|
|
36
|
+
num_bits[j] = not num_bits[j]
|
|
37
|
+
carry = 0 if num_bits[j] else 1
|
|
38
|
+
bool_data.append(sign_bit)
|
|
39
|
+
bool_data.extend(num_bits)
|
|
40
|
+
self.total_bits = len(bool_data)
|
|
41
|
+
super().__init__(0, self.total_bits, False, IntBitTag, False)
|
|
42
|
+
for idx in range(self.total_bits):
|
|
43
|
+
if idx < self.size:
|
|
44
|
+
super().__setitem__(idx, bool_data[idx])
|
|
45
|
+
else:
|
|
46
|
+
super().append(bool_data[idx])
|
|
47
|
+
for i in range(0, self.total_bits, self.bit_length):
|
|
48
|
+
if i < self.size:
|
|
49
|
+
bit_tag = super().__getitem__(i)
|
|
50
|
+
bit_tag.is_sign_bit = True
|
|
51
|
+
|
|
52
|
+
def to_int(self, bit_chunk):
|
|
53
|
+
sign_bit = bit_chunk[0].value
|
|
54
|
+
num_bits = [bit.value for bit in bit_chunk[1:]]
|
|
55
|
+
if not sign_bit:
|
|
56
|
+
num = 0
|
|
57
|
+
for j in range(len(num_bits)):
|
|
58
|
+
if num_bits[j]:
|
|
59
|
+
num += (1 << j)
|
|
60
|
+
else:
|
|
61
|
+
num_bits_inv = [not b for b in num_bits]
|
|
62
|
+
carry = 1
|
|
63
|
+
for j in range(len(num_bits_inv)):
|
|
64
|
+
if carry:
|
|
65
|
+
num_bits_inv[j] = not num_bits_inv[j]
|
|
66
|
+
carry = 0 if num_bits_inv[j] else 1
|
|
67
|
+
num = 0
|
|
68
|
+
for j in range(len(num_bits_inv)):
|
|
69
|
+
if num_bits_inv[j]:
|
|
70
|
+
num += (1 << j)
|
|
71
|
+
num = -num
|
|
72
|
+
return num
|
|
73
|
+
|
|
74
|
+
def __getitem__(self, key):
|
|
75
|
+
if isinstance(key, slice):
|
|
76
|
+
start, stop, step = key.indices(len(self))
|
|
77
|
+
result = []
|
|
78
|
+
for i in range(start, stop, step):
|
|
79
|
+
block_start = i * self.bit_length
|
|
80
|
+
block_end = block_start + self.bit_length
|
|
81
|
+
if block_end > self.size:
|
|
82
|
+
raise IndexError("索引超出范围")
|
|
83
|
+
bit_chunk = [super().__getitem__(j) for j in range(block_start, block_end)]
|
|
84
|
+
num = self.to_int(bit_chunk)
|
|
85
|
+
result.append(num)
|
|
86
|
+
return IntHybridArray(result, self.bit_length)
|
|
87
|
+
key = key if key >= 0 else key + len(self)
|
|
88
|
+
if not (0 <= key < len(self)):
|
|
89
|
+
raise IndexError("索引超出范围")
|
|
90
|
+
block_start = key * self.bit_length
|
|
91
|
+
block_end = block_start + self.bit_length
|
|
92
|
+
if block_end > self.size:
|
|
93
|
+
raise IndexError("索引超出范围")
|
|
94
|
+
bit_chunk = [super().__getitem__(j) for j in range(block_start, block_end)]
|
|
95
|
+
return self.to_int(bit_chunk)
|
|
96
|
+
|
|
97
|
+
def __setitem__(self, key, value):
|
|
98
|
+
value = int(value)
|
|
99
|
+
if isinstance(key, slice):
|
|
100
|
+
start, stop, step = key.indices(len(self))
|
|
101
|
+
values = list(value) if isinstance(value, (list, tuple, IntHybridArray)) else [value] * ((stop - start + step - 1) // step)
|
|
102
|
+
idx = 0
|
|
103
|
+
for int_idx in range(start, stop, step):
|
|
104
|
+
block_start = int_idx * self.bit_length
|
|
105
|
+
block_end = block_start + self.bit_length
|
|
106
|
+
if block_end > self.size:
|
|
107
|
+
raise IndexError("索引超出范围")
|
|
108
|
+
num = values[idx % len(values)]
|
|
109
|
+
if num >= 0:
|
|
110
|
+
sign_bit = False
|
|
111
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
112
|
+
else:
|
|
113
|
+
sign_bit = True
|
|
114
|
+
abs_num = abs(num)
|
|
115
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
116
|
+
carry = 1
|
|
117
|
+
for j in range(len(num_bits)):
|
|
118
|
+
if carry:
|
|
119
|
+
num_bits[j] = not num_bits[j]
|
|
120
|
+
carry = 0 if num_bits[j] else 1
|
|
121
|
+
bool_data = [sign_bit] + num_bits
|
|
122
|
+
for bit_idx in range(self.bit_length):
|
|
123
|
+
super().__setitem__(block_start + bit_idx, bool_data[bit_idx])
|
|
124
|
+
idx += 1
|
|
125
|
+
return
|
|
126
|
+
key = key if key >= 0 else key + len(self)
|
|
127
|
+
if not (0 <= key < len(self)):
|
|
128
|
+
raise IndexError("索引超出范围")
|
|
129
|
+
block_start = key * self.bit_length
|
|
130
|
+
block_end = block_start + self.bit_length
|
|
131
|
+
if block_end > self.size:
|
|
132
|
+
raise IndexError("索引超出范围")
|
|
133
|
+
num = value
|
|
134
|
+
if num >= 0:
|
|
135
|
+
sign_bit = False
|
|
136
|
+
num_bits = [bool((num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
137
|
+
else:
|
|
138
|
+
sign_bit = True
|
|
139
|
+
abs_num = abs(num)
|
|
140
|
+
num_bits = [not bool((abs_num >> i) & 1) for i in range(self.bit_length - 1)]
|
|
141
|
+
carry = 1
|
|
142
|
+
for j in range(len(num_bits)):
|
|
143
|
+
if carry:
|
|
144
|
+
num_bits[j] = not num_bits[j]
|
|
145
|
+
carry = 0 if num_bits[j] else 1
|
|
146
|
+
bool_data = [sign_bit] + num_bits
|
|
147
|
+
for bit_idx in range(self.bit_length):
|
|
148
|
+
super().__setitem__(block_start + bit_idx, bool_data[bit_idx])
|
|
149
|
+
|
|
150
|
+
def __iter__(self):
|
|
151
|
+
for i in range(0, self.total_bits, self.bit_length):
|
|
152
|
+
if i + self.bit_length > self.size:
|
|
153
|
+
break
|
|
154
|
+
bit_chunk = [super().__getitem__(j) for j in range(i, i + self.bit_length)]
|
|
155
|
+
yield self.to_int(bit_chunk)
|
|
156
|
+
|
|
157
|
+
def __str__(self):
|
|
158
|
+
return f"IntHybridArray([{', '.join(map(str, self))}])"
|
|
159
|
+
__repr__ = __str__
|
|
160
|
+
|
|
161
|
+
def __len__(self):
|
|
162
|
+
return self.total_bits // self.bit_length
|
|
163
|
+
def __delitem__(self, index: int = -1):
|
|
164
|
+
index = index if index >= 0 else index + len(self)
|
|
165
|
+
if not (0 <= index < len(self)):
|
|
166
|
+
raise IndexError("删除索引超出范围")
|
|
167
|
+
target_num = self[index]
|
|
168
|
+
pop_bit_start = index * self.bit_length
|
|
169
|
+
pop_bit_end = pop_bit_start + self.bit_length
|
|
170
|
+
for _ in range(self.bit_length):
|
|
171
|
+
super().__delitem__(pop_bit_start)
|
|
172
|
+
self.total_bits -= self.bit_length
|
|
173
|
+
def index(self, value):
|
|
174
|
+
value = int(value)
|
|
175
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
176
|
+
for idx in range(len(self)+2>>2):
|
|
177
|
+
if self[idx] == value:
|
|
178
|
+
return idx
|
|
179
|
+
elif self[-idx] == value:
|
|
180
|
+
x = len(self)-idx
|
|
181
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
182
|
+
return x
|
|
183
|
+
raise ValueError(x)
|
|
184
|
+
def rindex(self, value):
|
|
185
|
+
value = int(value)
|
|
186
|
+
x = f"{value} 不在 IntHybridArray 中"
|
|
187
|
+
for idx in range(len(self)+2>>2):
|
|
188
|
+
if self[-idx] == value:
|
|
189
|
+
return -idx
|
|
190
|
+
elif self[idx] == value:
|
|
191
|
+
x = -(len(self)-idx)
|
|
192
|
+
if x != f"{value} 不在 IntHybridArray 中":
|
|
193
|
+
return x
|
|
194
|
+
raise ValueError(x)
|
|
195
|
+
def extend(self, iterable:Iterable) -> None:
|
|
196
|
+
if isinstance(iterable, (Iterator, Generator, map)):
|
|
197
|
+
iterable,copy = itertools.tee(iterable, 2)
|
|
198
|
+
len_ = sum(1 for _ in copy)
|
|
199
|
+
else:
|
|
200
|
+
len_ = len(iterable)
|
|
201
|
+
self.total_bits += len_*self.bit_length
|
|
202
|
+
for i,j in zip(range(len_),iterable):
|
|
203
|
+
self[-i-1] = j
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bool-hybrid-array
|
|
3
|
-
Version: 9.10.
|
|
3
|
+
Version: 9.10.21
|
|
4
4
|
Summary: 一个高效的布尔数组(密集+稀疏混合存储,节省内存)
|
|
5
5
|
Home-page: https://github.com/BKsell/bool-hybrid-array
|
|
6
6
|
Author: 蔡靖杰
|
|
@@ -10,12 +10,20 @@ Project-URL: GitHub 中文镜像, https://www.github-zh.com/projects/1083175506-
|
|
|
10
10
|
Project-URL: Issue 反馈(主站), https://github.com/BKsell/bool-hybrid-array/issues
|
|
11
11
|
Keywords: boolean array,compact storage
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
21
|
Classifier: Operating System :: OS Independent
|
|
15
22
|
Requires-Python: >=3.8
|
|
16
23
|
Description-Content-Type: text/markdown
|
|
17
24
|
License-File: LICENSE
|
|
18
25
|
Requires-Dist: numpy>=1.19.0
|
|
26
|
+
Provides-Extra: int-array
|
|
19
27
|
Dynamic: author
|
|
20
28
|
Dynamic: author-email
|
|
21
29
|
Dynamic: classifier
|
|
@@ -25,6 +33,7 @@ Dynamic: home-page
|
|
|
25
33
|
Dynamic: keywords
|
|
26
34
|
Dynamic: license-file
|
|
27
35
|
Dynamic: project-url
|
|
36
|
+
Dynamic: provides-extra
|
|
28
37
|
Dynamic: requires-dist
|
|
29
38
|
Dynamic: requires-python
|
|
30
39
|
Dynamic: summary
|
|
@@ -384,6 +393,24 @@ BoolHybridArr([False,False,False,False,True,True,False,True,True,False]),
|
|
|
384
393
|
try:numba_opt()
|
|
385
394
|
except:print("请先安装numba库!!!")
|
|
386
395
|
|
|
396
|
+
#int_array模块(9.10.10新增):
|
|
397
|
+
|
|
398
|
+
max_num = (1 << 256) - 1
|
|
399
|
+
min_num = -max_num
|
|
400
|
+
|
|
401
|
+
# 1. IntHybridArray:257位完美存储
|
|
402
|
+
arr_hybrid = int_array.IntHybridArray([max_num, min_num, 123456], bit_length=257)
|
|
403
|
+
print("✅ IntHybridArray存储结果:")
|
|
404
|
+
print(f"最大值:{arr_hybrid[0]}")
|
|
405
|
+
print(f"最小值:{arr_hybrid[1]}")
|
|
406
|
+
|
|
407
|
+
# 2. NumPy:用最大的int64尝试存储(必然失败)
|
|
408
|
+
try:
|
|
409
|
+
arr_np = np.array([max_num, min_num, 123456], dtype=np.int64)
|
|
410
|
+
print("\n❌ NumPy存储结果:", arr_np)
|
|
411
|
+
except OverflowError as e:
|
|
412
|
+
print(f"\n❌ NumPy存储失败:{e}")
|
|
413
|
+
|
|
387
414
|
```
|
|
388
415
|
|
|
389
416
|
## 性能优势
|
|
@@ -397,7 +424,7 @@ except:print("请先安装numba库!!!")
|
|
|
397
424
|
|
|
398
425
|
## 版本历史
|
|
399
426
|
|
|
400
|
-
|
|
427
|
+
- **7.8.13**:PyPI上的初始版本,支持基本功能和自动存储优化
|
|
401
428
|
* **7.9.0**:添加TruesArray和FalsesArray
|
|
402
429
|
* **7.9.1**:修复介绍的bug,增加copy功能
|
|
403
430
|
* **7.9.2**:新增find()方法
|
|
@@ -439,7 +466,7 @@ except:print("请先安装numba库!!!")
|
|
|
439
466
|
* **7.14.4**:修复in的错误×3
|
|
440
467
|
* **7.14.5**:修复in的错误×4
|
|
441
468
|
* **7.14.6**:优化arr.large的类型
|
|
442
|
-
|
|
469
|
+
- **8.0.0**:兼容numpy数组
|
|
443
470
|
* **8.0.1**:修复8.0.0兼容numpy数组时没有形状参数的问题
|
|
444
471
|
* **8.0.2**:移除bool_hybrid_dtype,改用object
|
|
445
472
|
* **8.1.0**:利用ctypes加速密集部分的一些方法
|
|
@@ -451,7 +478,7 @@ except:print("请先安装numba库!!!")
|
|
|
451
478
|
* **8.2.0**:支持哈希
|
|
452
479
|
* **8.2.1**:修复8.2.0版本中的NameError
|
|
453
480
|
* **8.2.2**:修复8.2.1版本中的IndexError
|
|
454
|
-
|
|
481
|
+
- --9.0.0--:详情见上
|
|
455
482
|
* **9.0.1**:小更新,优化optimize方法
|
|
456
483
|
* **9.1.0**:新增二维数组的optimize与memory\_usage,优化二维数组的位运算,给BHA\_Bool新增__rand__、**ror**、__rxor__等等
|
|
457
484
|
* **9.1.1**:修复9.1.0版本中的TypeError: unsupported operand type(s) for +: 'int' and 'method'错误
|
|
@@ -528,9 +555,22 @@ except:print("请先安装numba库!!!")
|
|
|
528
555
|
* **9.10.7**:修复了RecursionError: maximum recursion depth exceeded错误
|
|
529
556
|
* **9.10.8**:给Create_BHA新增了mmap优化
|
|
530
557
|
* **9.10.9**:修复9.10.8版本中的NameError错误
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
558
|
+
* **9.10.10**:新增int_array模块
|
|
559
|
+
* **9.10.11**:修复NameError: name 'int_array' is not defined. Did you mean: 'bytearray'?的错误
|
|
560
|
+
* **9.10.12**:把find方法的返回值改为IntHybridArray
|
|
561
|
+
* **9.10.13**:给IntHybridArray新增多种列表操作
|
|
562
|
+
* **9.10.14**:修复IntHybridArray中因单个 0 导致所有数字位长被压缩到 1的问题
|
|
563
|
+
* **9.10.15**:修复IntHybridArray变成布尔数组的错误
|
|
564
|
+
* **9.10.16**:新增Python 3.14时的jit优化加速
|
|
565
|
+
* **9.10.17**:给保护字典添加__import__方法,支持from导入
|
|
566
|
+
* **9.10.18**:新增BoolHybridArray的序列化和反序列化支持
|
|
567
|
+
* **9.10.18.post1**:修复TypeError: cannot pickle 'itertools._tee' object错误
|
|
568
|
+
* **9.10.18.post2**:尝试修复“满屏错误”的问题
|
|
569
|
+
* **9.10.18.post3**:尝试修复“满屏错误”的问题×2
|
|
570
|
+
* **9.10.18.post4**:尝试修复“满屏错误”的问题×3
|
|
571
|
+
* **9.10.19**:和9.10.18.post4相同,正式版本发布
|
|
572
|
+
* **9.10.20**:优化性能,增加BHA_jit_log日志
|
|
573
|
+
* **9.10.21**:优化Ask_BHA,移除BHA_jit_log日志
|
|
534
574
|
|
|
535
575
|
|
|
536
576
|
## **彩蛋:**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
bool_hybrid_array/__init__.py,sha256=r04Lq3_vRUkxPYT4oLIz8wLBhbRP70UvXGQKMpt8tps,955
|
|
2
|
+
bool_hybrid_array/__main__.py,sha256=3MsUAXMj6Pe1EzP7YreuUePbXZeQvFSCnejnTeS42kU,8324
|
|
3
|
+
bool_hybrid_array/core.py,sha256=MNxYpZdtY36ElBbdqYjNUp1fJwYEHSTsc1Y323Cytro,37984
|
|
4
|
+
bool_hybrid_array/秘密.md,sha256=Ii2NvXmv-Ktu04zJsGLcQZvlzT4gOatByE4B2wTK1Ks,48
|
|
5
|
+
bool_hybrid_array/int_array/__init__.py,sha256=acjFchFu3k9CQndDbvKfSIyfMMAbgprz8Skf1a4_dKY,8578
|
|
6
|
+
bool_hybrid_array-9.10.21.dist-info/licenses/LICENSE,sha256=Sg4rnGXkBDYkwJCWyxdWp5H60rhVAxpNvFh_l3JWZdY,1070
|
|
7
|
+
bool_hybrid_array-9.10.21.dist-info/METADATA,sha256=k037Kzz3zMnTbD-zaIfSacesqeVIThAW2Eu6_AlEiXk,23491
|
|
8
|
+
bool_hybrid_array-9.10.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
bool_hybrid_array-9.10.21.dist-info/top_level.txt,sha256=vk-TD77wuVQsN1rJ6uVWZX4sC_wya_WplRDwQKJoBZM,18
|
|
10
|
+
bool_hybrid_array-9.10.21.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
bool_hybrid_array/__init__.py,sha256=HFRGhLIvAvAwzL-DpDyseAv9FI__5jI3MAdXJ_o2zd4,756
|
|
2
|
-
bool_hybrid_array/__main__.py,sha256=pE9jECC2i2_13HJnI3qPav1YaggfUs-gdScabvRpD9I,7728
|
|
3
|
-
bool_hybrid_array/core.py,sha256=_E5kG6NjqYdV4KSkDxbO7R9tXOz22_GXPA-TQq6Bzlo,36485
|
|
4
|
-
bool_hybrid_array-9.10.9.dist-info/licenses/LICENSE,sha256=Sg4rnGXkBDYkwJCWyxdWp5H60rhVAxpNvFh_l3JWZdY,1070
|
|
5
|
-
bool_hybrid_array-9.10.9.dist-info/METADATA,sha256=Kpl_1o--9_Ytg7spjkCVDakUG6bDpiPuFPtBpKYWmvs,21400
|
|
6
|
-
bool_hybrid_array-9.10.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
bool_hybrid_array-9.10.9.dist-info/top_level.txt,sha256=vk-TD77wuVQsN1rJ6uVWZX4sC_wya_WplRDwQKJoBZM,18
|
|
8
|
-
bool_hybrid_array-9.10.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|