5

I'm trying to elementwise & and elementwise | 2 lists of 8 lists of 6 binary digits, and it is working very oddly. c1 and c2 start as tuples of length 8 with elements that are tuples of length 6, and res starts out as a list version of c1.

anding:

for x in range(8):
    for y in range(6):
        res[x][y] = (c1[:][x][y])*(c2[:][x][y])

oring:

for x in range(8):
    for y in range(6):
        res[x][y] = int(c1[:][x][y] or c2[:][x][y])

An example:

c1:        ((1, 0, 0, 0, 1, 1), (1, 1, 0, 0, 0, 1), (1, 1, 1, 0, 0, 0), (0, 1, 1, 1, 1, 0), (1, 0, 0, 0, 1, 1), (0, 1, 1, 0, 0, 0), (1, 1, 0, 1, 0, 0), (0, 1, 0, 0, 1, 0))
c2:        ((1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 1, 0), (0, 1, 1, 0, 1, 0), (0, 0, 0, 0, 1, 1), (1, 1, 0, 0, 1, 0), (1, 0, 1, 0, 1, 0), (0, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 0))
anding res:[[1, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0]]
oring res: [[1, 1, 0, 0, 1, 1], [1, 1, 0, 1, 1, 1], [1, 1, 1, 0, 1, 0], [0, 1, 1, 1, 1, 1], [1, 1, 0, 0, 1, 1], [1, 1, 1, 0, 1, 0], [1, 1, 0, 1, 0, 1], [0, 1, 1, 0, 1, 0]]

Other inputs for c1 and can be messed up in much more than the first sublist.

Edit: This has been resolved. It was most likely alias issues in other parts of the code, and I just ended up using list comprehensions.

6
  • 2
    Looping by index in Python is just generally a really bad idea. Use list comprehensions to achieve this kind of thing instead. Commented Apr 16, 2013 at 18:18
  • Where did you "initialize" res? Commented Apr 16, 2013 at 18:19
  • 1
    use & for ANDing and | for ORing. Commented Apr 16, 2013 at 18:24
  • For oring res, shouldn't the first element be [1, 0, 1, 1, 1, 1]? Commented Apr 16, 2013 at 18:26
  • There are better ways to write this code, but it doesn't contain any logical errors. When I run it, I get expected results. The problem must be elsewhere. Commented Apr 16, 2013 at 18:26

5 Answers 5

23

You could just use NumPy:

In [7]: import numpy as np
In [8]: c1 = np.array(c1)    
In [9]: c2 = np.array(c2)

In [10]: c1 & c2
In [11]: c1 | c2
Sign up to request clarification or add additional context in comments.

2 Comments

What if I've got [c1, c2, c3, ... c10] and I want c1 & c2 & ... & c10? Is there a shortcut way to do this?
np.logical_and.reduce([c1, c2, ..., c10])
11

Why not simply trying something like this using list comprehensions:

c1 = ((1, 0, 0, 0, 1, 1), (1, 1, 0, 0, 0, 1), (1, 1, 1, 0, 0, 0))
c2 = ((1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 1, 0), (0, 1, 1, 0, 1, 0))

print('Bitwise or:  ', [[k | l for k, l in zip(i, j)] for i, j in zip(c1, c2)])
print('Bitwise and: ', [[k & l for k, l in zip(i, j)] for i, j in zip(c1, c2)])

1 Comment

Because I code sporadically as a hobby, and I didn't know about them.
2

You can always roll your own class:

class BitList(list):
    def anditems(self,other):
        return [se & so for se,so in zip(self,other)]

    def oritems(self,other):
        return [se | so for se,so in zip(self,other)]    

    def xoritems(self,other):
        return [se ^ so for se,so in zip(self,other)]    

print BitList([1,1,0,0,1,1]).xoritems([1,1,1,1,1,1])
    # [0, 0, 1, 1, 0, 0]
print BitList([1,1,0,0,1,1]).oritems([1,1,1,1,1,1])
    # [1, 1, 1, 1, 1, 1]
print BitList([1,1,0,0,1,1]).anditems([1,1,1,1,1,1]) 
    # [1, 1, 0, 0, 1, 1]

Then just deal with the nested sublists separately:

c1=((1, 0, 0, 0, 1, 1), (1, 1, 0, 0, 0, 1), (1, 1, 1, 0, 0, 0), (0, 1, 1, 1, 1, 0), (1, 0, 0, 0, 1, 1), (0, 1, 1, 0, 0, 0), (1, 1, 0, 1, 0, 0), (0, 1, 0, 0, 1, 0))
c2=((1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 1, 0), (0, 1, 1, 0, 1, 0), (0, 0, 0, 0, 1, 1), (1, 1, 0, 0, 1, 0), (1, 0, 1, 0, 1, 0), (0, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 0))


print [BitList(t1).anditems(t2) for t1,t2 in zip(c1,c2)]
print [BitList(t1).oritems(t2) for t1,t2 in zip(c1,c2)]

Comments

1

seems OK to me:

>>> c1 =  ((1, 0, 0, 0, 1, 1), (1, 1, 0, 0, 0, 1), (1, 1, 1, 0, 0, 0), (0, 1, 1, 1, 1, 0), (1, 0, 0, 0, 1, 1), (0, 1, 1, 0, 0, 0), (1, 1, 0, 1, 0, 0), (0, 1, 0, 0, 1, 0))
>>> c2 =  ((1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 1, 0), (0, 1, 1, 0, 1, 0), (0, 0, 0, 0, 1, 1), (1, 1, 0, 0, 1, 0), (1, 0, 1, 0, 1, 0), (0, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 0))
>>> res = [[None]*6 for _ in range(8)]
>>> for x in range(8):
...     for y in range(6):
...         res[x][y] = c1[x][y] & c2[x][y]
... 
>>> print res
[[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0], [1, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0]]
>>> for x in range(8):
...     for y in range(6):
...         res[x][y] = c1[x][y] | c2[x][y]
... 
>>> print res
[[1, 0, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1], [1, 1, 1, 0, 1, 0], [0, 1, 1, 1, 1, 1], [1, 1, 0, 0, 1, 1], [1, 1, 1, 0, 1, 0], [1, 1, 0, 1, 0, 1], [0, 1, 1, 0, 1, 0]]
>>> 

I used & and | for the bitwise operators, but it really shouldn't make a difference since you're just using 1s and 0s. I suspect that you initialized res = [[None]*6]*8 (or similar) which is causing some of your sublists to be referencing the same list.

3 Comments

You did the part that requires thought :)
I don't know that it required much thinking ... Mostly just copy-pasting like a well trained ape.
That was my thought too, but I inserted [:]s everywhere I could, including places I knew it was superfluosu, and it still didn't work.
0
def bitwise(a, b, core): 
  return [int(core(pred, true)) for pred, true in zip(pred_list, true_list)]


pred_list = [1, 1, 0, 0]   # prediction
true_list = [1, 0, 1, 0]   # true

print("| true pos")
true_positive = bitwise(pred_list, true_list, lambda pred, true: pred==1 and true==1) 
print(true_positive)

This is a piece of my F_Score.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.