Binary Sort on Python List __xor__

MRAB python at mrabarnett.plus.com
Sat May 30 20:28:36 EDT 2020


On 2020-05-30 23:52, evan.schalton at gmail.com wrote:
> I frequently use binary as bool placeholders and find myself filtering lists based on those bools, this seems to have a similar semantic meaning as the bit wise ^ or __xor__ operator and could add syntactic sugar to the base list class.
> 
> Use Case:
> 
> Controlling a stepper at half-step has the following cycle steps:
> 
> CYCLE = [
>    [1,0,0,0],
>    [1,1,0,0],
>    [0,1,0,0],
>    [0,1,1,0],
>    [0,0,1,0],
>    [0,0,1,1],
>    [0,0,0,1],
>    [1,0,0,1],
> ]
> 
> which can be represented as follows:
> 
> CYCLE = [
>      1<<3,
>      1<<3|1<<2,
>      1<<2,
>      1<<2|1<<1,
>      1<<1,
>      1<<1|1<<0,
>      1<<0,
>      1<<3|1<<0
> ]
> 
> or more cleanly:
> 
> CYCLE = [8, 12, 4, 6, 2, 3, 1, 9]
> 
Or more clearly:

CYCLE = [
   0b1000,
   0b1100,
   0b0100,
   0b0110,
   0b0010,
   0b0011,
   0b0001,
   0b1001,
]

> on a raspberrypi, using (for illustration's sake) GPIO pins 1,2,3,4 I'd like to use the __xor__ method (currently not implemented) to perform the bit-wise filter as follows:

Bit-masking is done with a bitwise AND, so I'd expect the __and__ method 
would be used. The __xor__ method would be for bit-toggling.

> 
> class MyList(list):
>      def __init__(self, *args):
>          super().__init__(args)
>      
>      def __xor__(self, num):
>          return [self[i] for i in [-index-1 for index, i in enumerate(bin(num)[:1:-1]) if i !='0']][::-1]
> 
> PINS = MyList(1,2,3,4)
> 
> PINS ^ 8
> # [1]
> 
> PINS ^ 12
> # [1, 2]
> 
> PINS ^ 4
> # [2]
> 
> PINS ^ 6
> # [2, 3]
> 
> PINS ^ 2
> # [3]
> 
> PINS ^ 3
> # [3, 4]
> 
> PINS ^ 1
> # [4]
> 
> PINS ^ 9
> # [1, 4]
> 
> The need here isn't strictly pi/stepper related; I've run into this several times in the past when evaluating combinations * permutations of items where a bitwise filter would be useful.
> 
Do you really need a class for this?

CYCLE = [
   0b1000,
   0b1100,
   0b0100,
   0b0110,
   0b0010,
   0b0011,
   0b0001,
   0b1001,
]

PINS = [1, 2, 3, 4]

def bit_filter(pins, bits):
     return [pin for pin, bit in zip(PINS, format(bits, '04b')) if bit 
== '1']

bit_filter(PINS, 0b1000)
# [1]
bit_filter(PINS, 0b0100)
# [2]
bit_filter(PINS, 0b0110)
# [2, 3]
bit_filter(PINS, 0b0010)
# [3]
bit_filter(PINS, 0b0011)
# [3, 4]
bit_filter(PINS, 0b0001)
# [4]
bit_filter(PINS, 0b1001)
# [1, 4]


More information about the Python-list mailing list