2010-10-15 10 views
22

Gibt es eine Python-Klasse oder ein Python-Modul, die eine Struktur implementieren, die dem BitSet ähnlich ist?Python entspricht Java's BitSet

+2

Für Nicht-Java-Programmierer, was ist ein BitSet? Was versuchst du zu erreichen? Selbst wenn kein Äquivalent existiert, könnte es eine gute, pythische Art geben, Ihr Problem zu lösen. –

+0

Grundsätzlich ist ein BitSet eine Bitfolge mit bitweisen Operationen, die auf sie angewendet werden können. Die Menge kann auch erweitert werden, indem Bits oder Bitsets an das Ende des aktuellen Bitsatzes angehängt werden –

Antwort

6

Werfen Sie einen Blick auf diese implementation in Python 3.

Die Umsetzung im Grunde macht Gebrauch von den integrierten in int-Typ, die in Python beliebiger Genauigkeit Integer-Typ ist 3 (wobei long ist das Python 2-Äquivalent).

#! /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