Python 相当于 Java 的 BitSet
Posted
技术标签:
【中文标题】Python 相当于 Java 的 BitSet【英文标题】:Python equivalent to Java's BitSet 【发布时间】:2011-04-26 03:44:06 【问题描述】:是否有实现类似于 BitSet 的结构的 Python 类或模块?
【问题讨论】:
对于非 Java 程序员,什么是 BitSet?你想达到什么目的?即使不存在等价物,也可能有一种很好的 Pythonic 方式来解决您的问题。 基本上,BitSet 是一串位,可以对其应用位操作。该集合也可以通过将位或位集附加到当前位集的末尾来扩展 【参考方案1】:我不建议在生产代码中使用,但为了竞争性编程、面试准备和乐趣,应该让自己熟悉一些摆弄。
b = 0 # The empty bitset :)
b |= 1 << i # Set
b & 1 << i # Test
b &= ~(1 << i) # Reset
b ^= 1 << i # Flip i
b = ~b # Flip all
【讨论】:
为什么不建议在生产代码中这样做?看起来简单高效。 它可能被某些人认为是晦涩难懂的,而且它对错字非常敏感!不过,它会很好地打包在一个类中。【参考方案2】:在 Python 3 中查看这个 implementation。
该实现基本上使用了内置的int
类型,它是Python 3 中的任意精度整数类型(其中long
是Python 2 的等价物)。
#! /usr/bin/env python3
"""
bitset.py
Written by Geremy Condra
Licensed under GPLv3
Released 3 May 2009
This module provides a simple bitset implementation
for Python.
"""
from collections import Sequence
import math
class Bitset(Sequence):
"""A very simple bitset implementation for Python.
Note that, like with normal numbers, the leftmost
index is the MSB, and like normal sequences, that
is 0.
Usage:
>>> b = Bitset(5)
>>> b
Bitset(101)
>>> b[:]
[True, False, True]
>>> b[0] = False
>>> b
Bitset(001)
>>> b << 1
Bitset(010)
>>> b >> 1
Bitset(000)
>>> b & 1
Bitset(001)
>>> b | 2
Bitset(011)
>>> b ^ 6
Bitset(111)
>>> ~b
Bitset(110)
"""
value = 0
length = 0
@classmethod
def from_sequence(cls, seq):
"""Iterates over the sequence to produce a new Bitset.
As in integers, the 0 position represents the LSB.
"""
n = 0
for index, value in enumerate(reversed(seq)):
n += 2**index * bool(int(value))
b = Bitset(n)
return b
def __init__(self, value=0, length=0):
"""Creates a Bitset with the given integer value."""
self.value = value
try: self.length = length or math.floor(math.log(value, 2)) + 1
except Exception: self.length = 0
def __and__(self, other):
b = Bitset(self.value & int(other))
b.length = max((self.length, b.length))
return b
def __or__(self, other):
b = Bitset(self.value | int(other))
b.length = max((self.length, b.length))
return b
def __invert__(self):
b = Bitset(~self.value)
b.length = max((self.length, b.length))
return b
def __xor__(self, value):
b = Bitset(self.value ^ int(value))
b.length = max((self.length, b.length))
return b
def __lshift__(self, value):
b = Bitset(self.value << int(value))
b.length = max((self.length, b.length))
return b
def __rshift__(self, value):
b = Bitset(self.value >> int(value))
b.length = max((self.length, b.length))
return b
def __eq__(self, other):
try:
return self.value == other.value
except Exception:
return self.value == other
def __int__(self):
return self.value
def __str__(self):
s = ""
for i in self[:]:
s += "1" if i else "0"
return s
def __repr__(self):
return "Bitset(%s)" % str(self)
def __getitem__(self, s):
"""Gets the specified position.
Like normal integers, 0 represents the MSB.
"""
try:
start, stop, step = s.indices(len(self))
results = []
for position in range(start, stop, step):
pos = len(self) - position - 1
results.append(bool(self.value & (1 << pos)))
return results
except:
pos = len(self) - s - 1
return bool(self.value & (1 << pos))
def __setitem__(self, s, value):
"""Sets the specified position/s to value.
Like normal integers, 0 represents the MSB.
"""
try:
start, stop, step = s.indices(len(self))
for position in range(start, stop, step):
pos = len(self) - position - 1
if value: self.value |= (1 << pos)
else: self.value &= ~(1 << pos)
maximum_position = max((start + 1, stop, len(self)))
self.length = maximum_position
except:
pos = len(self) - s - 1
if value: self.value |= (1 << pos)
else: self.value &= ~(1 << pos)
if len(self) < pos: self.length = pos
return self
def __iter__(self):
"""Iterates over the values in the bitset."""
for i in self[:]:
yield i
def __len__(self):
"""Returns the length of the bitset."""
return self.length
【讨论】:
【参考方案3】:您可能想看看我编写的一个名为 bitstring 的模块(完整文档 here),尽管对于需要尽可能快的简单案例,我仍然推荐 bitarray。
一些类似的问题:
What is the best way to do Bit Field manipulation in Python?
Does Python have a bitfield type?
Python Bitstream implementations
【讨论】:
【参考方案4】:标准库中什么都没有。试试:
http://pypi.python.org/pypi/bitarray
【讨论】:
以上是关于Python 相当于 Java 的 BitSet的主要内容,如果未能解决你的问题,请参考以下文章