【问题标题】:List of binary numbers: How many positions have a one and zero二进制数列表:有多少个位置有 1 和 0
【发布时间】:2021-02-24 06:55:02
【问题描述】:

我有一个整数列表,例如i=[1,7,3,1,5] 我首先将其转换为长度为 L 的相应二进制表示的列表,例如b=["001","111","011","001","101"]L=3

现在我想计算在二进制表示中有多少L 位置有1 以及零0。在我的示例中,结果将是return=2,因为这些条目的第三个(最后一个)位置总是有一个1。我很乐意发表任何评论。我认为,理想情况下,我应该同时进行许多 Xor 操作。但是,我不确定如何有效地做到这一点。

编辑:感谢您的许多回答!我必须检查哪一个是最快的。

【问题讨论】:

  • 答案不应该是 3 吗?
  • 请注意,我将您的问题回滚到以前的版本,因为您不应该使用答案将其变成后续问题。很高兴看到您现在在 Code Review 上发布了后续问题

标签: python numpy numba binary-operators


【解决方案1】:

一个观察结果是,如果您对所有数字进行 AND 以及所有数字的 OR,那么这两个结果的 XOR 将在满足条件的情况下为 1。

所以:

from functools import reduce
from operator import and_, or_

def count_mixed_bits(lst):
    xor = reduce(and_, lst) ^ reduce(or_, lst)
    return bin(xor).count("1")


count_mixed_bits([1,7,3,1,5])  # 2

【讨论】:

  • 感谢您的解释。这对我来说很有意义,而且看起来很简单
  • 我需要这个在 numba 函数中工作。因此,我尝试修改您的代码。也许您对 numba 也有一些专业知识?我不确定我的修改是否最佳。
  • 请不要修改您的问题以添加后续问题。如果您有后续问题,请考虑发布一个仅关注该问题的新问题。但是,如果您的后续问题是关于代码的大小和/或效率(当您有工作代码时),请考虑将其发布到 Code Review
【解决方案2】:

有一个接受长度的numpy.binary_repr 方法。不幸的是,它不能处理数组。但是您可以改为应用np.unravel_index 的功能:

def check(arr, lenght):
    positions = np.array(np.unravel_index(i, (2,)*lenght))
    return positions, np.sum(np.sum(positions, axis=1) != len(arr))

>>> positions, output = check(i, 3)
>>> print(positions)
>>> print(output)
[[0 1 0 0 1]
 [0 1 1 0 0]
 [1 1 1 1 1]]
2

【讨论】:

    【解决方案3】:

    这里有一个解决方案,我怀疑效率不是很高,但是很容易理解。

    我遍历数字并找到唯一的集合,然后计算集合长度为 2 的条目数:

    # create a binary list of 3 elements from input list of integers
    i=[1,7,3,1,5]
    b=['{0:03b}'.format(x) for x in i]
    
    # loop over the digit position (1,2,3)
    cnt=[]
    for pos in range(3):
        cnt.append(len(set([c[pos] for c in b])))
    
    # cnt now contains a list of either 2(=both 1 and 0 present) or 1 (unique)
    # so now we count the number of entries with "2"
    result=cnt.count(2)
    print (result)
    

    答案:

    2
    

    【讨论】:

      【解决方案4】:

      首先,您的问题用 numpy 标记,但您的数组不是 numpy 数组。 这是一个使用 numpy 的解决方案:

      import numpy as np
      
      def has_zeroes_and_ones_at_index(arr, index_from_right):
          shifted_arr = np.right_shift(arr, index_from_right)
          has_one_at_index = shifted_arr % 2 == 1
          return(True in has_one_at_index and False in has_one_at_index)
      
      arr = np.array([1, 7, 3, 1, 5])
      res= has_zeroes_and_ones_at_index(arr, 1)
      print(res)
      

      因为数字以二进制形式存储,我们可以使用位移将数字的所有位向右移动,然后查看最后一位。我们之前不必将它们转换为二进制格式。 5 (101) 右移一位 -> 2 (010)

      然后我们创建一个掩码来查看哪些数字的最后一位为 1,并在掩码中至少有一个 True 元素和一个 false 元素时返回 True。

      【讨论】:

      • 很好地使用了位移,我将数组更正为问题的数组,因为您的加法 2 使结果始终为真。另外,请注意,它并不能完全回答问题,因为仍然需要遍历位位置并计算 True 的数量。
      【解决方案5】:

      您可以为此任务使用 python 位运算符。

      def find(aList, nn):
          return sum( 
            filter( 
              lambda bb: bb > 0 ,
              (
                ( 1 <= (sum( (aa & 1<<kk) > 0 for aa in aList)) < len(aList) )
                for kk in range(nn)
              )
            )
          )
      

      >>> find([1,7,3,1,5],3)
      2
      >>> find([],3)
      0
      >>> find([7],3)
      0
      >>> find([7,1],3)
      2
      >>> find([7,1,7],3)
      2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-20
        • 2019-09-04
        • 2018-03-16
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        • 2021-03-10
        • 2022-11-27
        相关资源
        最近更新 更多