Wiper
Wiper

Reputation: 95

Itertools binary list with fixed values

I have some raw binary and I am unsure of some of the bits due to bad reading.

I made a list of the frequency that each bit is either 1 or 0. Some bits were always 0 or 1 but some are hard to determine. The real list unlike the sample below has 255 items. There is only 10 bits that are uncertain, so I feel it can be brute-forced.

[ 0.0, 0.35555555555555557, 1.0, 1.0, 0.4388888888888889, 0.0, 0.35555555555555557, 1.0]

x marks the uncertain values, f marking fixed.

[ f, x, f, f, x, f, x, f]

How can I use itertools to get every combination where x could be either 0 or 1, outputting a list of possibilities yet keeping the known values fixed ?

[ 0, 0, 1, 1, 0, 0, 0, 1]
[ 0, 1, 1, 1, 0, 0, 0, 1]
...
[ 0, 1, 1, 1, 1, 0, 1, 1]

Upvotes: 2

Views: 126

Answers (2)

Thierry Lathuille
Thierry Lathuille

Reputation: 24242

You can create a list of bad indices, then use itertools.product to produce all possible combinations of the bits at these indices:

from itertools import product

def possible_patterns(data):
    bad_indices = [i for i, bit in enumerate(data) if bit not in [0, 1]]

    for replacement in product([0, 1], repeat=len(bad_indices)):
        for index, bit in zip(bad_indices, replacement):
            data[index] = bit
        yield data
        
data = [ 0.0, 0.35555555555555557, 1.0, 1.0, 0.4388888888888889, 0.0, 0.35555555555555557, 1.0]

for pattern in possible_patterns(data):
    print(pattern)

Output:

[0.0, 0, 1.0, 1.0, 0, 0.0, 0, 1.0]
[0.0, 0, 1.0, 1.0, 0, 0.0, 1, 1.0]
[0.0, 0, 1.0, 1.0, 1, 0.0, 0, 1.0]
[0.0, 0, 1.0, 1.0, 1, 0.0, 1, 1.0]
[0.0, 1, 1.0, 1.0, 0, 0.0, 0, 1.0]
[0.0, 1, 1.0, 1.0, 0, 0.0, 1, 1.0]
[0.0, 1, 1.0, 1.0, 1, 0.0, 0, 1.0]
[0.0, 1, 1.0, 1.0, 1, 0.0, 1, 1.0]

Upvotes: 2

Yann
Yann

Reputation: 2532

You need itertools.product

Code example:

from itertools import product

a = [ 0.0, 0.35555555555555557, 1.0, 1.0, 0.4388888888888889, 0.0, 0.35555555555555557, 1.0]
m = [i for i, v in enumerate(a) if v not in (0.0, 1.0)]

for v in product((0.0, 1.0), repeat=len(m)):
    for i in range(len(m)):
        a[m[i]] = v[i]
    print(a)  # iterate over combinations

Upvotes: 1

Related Questions