【问题标题】:Python: Bitwise-like list operationsPython:类似位的列表操作
【发布时间】:2013-04-16 18:17:16
【问题描述】:

我正在尝试按元素 & 和按元素 | 2 个 8 个 6 个二进制数字列表的列表,它的工作非常奇怪。 c1 和 c2 以长度为 8 的元组开始,元素长度为 6 的元组,res 以 c1 的列表版本开始。

安定:

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

排序:

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

一个例子:

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]]

c1 的其他输入,可能比第一个子列表更混乱。

编辑:已解决。这很可能是代码其他部分的别名问题,我最终使用了列表推导。

【问题讨论】:

  • 在 Python 中按索引循环通常是一个非常糟糕的主意。改用list comprehensions来实现这种东西。
  • 你在哪里“初始化”了资源?
  • 使用& 进行ANDing 和| 进行ORing。
  • 对于oring res,第一个元素不应该是[1, 0, 1, 1, 1, 1]吗?
  • 有更好的方法来编写这段代码,但它不包含任何逻辑错误。当我运行它时,我得到了预期的结果。问题一定出在其他地方。

标签: python list


【解决方案1】:

你可以使用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

【讨论】:

  • 如果我有 [c1, c2, c3, ... c10] 并且我想要 c1 & c2 & ... & c10 怎么办?有没有捷径可以做到这一点?
  • np.logical_and.reduce([c1, c2, ..., c10])
【解决方案2】:

为什么不简单地使用列表推导来尝试这样的事情:

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)])

【讨论】:

  • 因为我偶尔将编码作为一种爱好,而我并不了解它们。
【解决方案3】:

你总是可以推出自己的课程:

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]

那就单独处理嵌套的子列表:

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)]

【讨论】:

    【解决方案4】:

    我觉得还可以:

    >>> 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]]
    >>> 
    

    我将&| 用于按位运算符,但由于您只是使用1 和0,因此它确实不应该有所作为。我怀疑你初始化了res = [[None]*6]*8(或类似的),这导致你的一些子列表引用了同一个列表。

    【讨论】:

    • 你做了需要思考的部分:)
    • 我不知道这需要多少思考......大多只是像训练有素的猿一样复制粘贴。
    • 这也是我的想法,但我在所有可能的地方都插入了 [:],包括我知道它是多余的地方,但它仍然不起作用。
    【解决方案5】:
    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)
    

    这是我的 F_Score 的一部分。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 2013-05-09
      • 1970-01-01
      相关资源
      最近更新 更多