【问题标题】:Combine Bitflags组合位标志
【发布时间】:2017-10-22 06:38:45
【问题描述】:

我有几个标志:

    None = 0
    HR = 1
    HD = 2,
    DT = 4,
    Fl = 8
..

我想创建一个输入某个标志的函数,比如说:6。

返回的应该是 HDDT,因为 2 | 4 = 6。 也可能发生 3 个或更多标志组合或仅一个标志。 例如: 7 = 1 | 2 | 4 => HRHDDT。

如何根据标志值返回连接字符串?

在我的例子中,枚举有更多的条目,这会使简单的 if 语句非常不舒服,因为我必须涵盖数百个案例。

有什么聪明的解决办法吗?

【问题讨论】:

  • 标志是如何存储的?
  • 我还没有存储它们 - 我知道这些值,但我不确定集成它们的最佳方法是什么。直接在 if 语句中,通过创建某种枚举..?
  • 我会用字典
  • 输入 0 的逻辑答案是空字符串,是吗?

标签: python flags


【解决方案1】:

假设我们在某处有一个具有 2 次幂的列表:

flags = ['HR','HD','DT','Fl']

那么你可以编写如下函数:

def power2():
    i = 1
    while True:
        yield i
        i *= 2

def obtain_flag(val):
    if val:
        return ''.join([f for f,i in zip(flags,power2()) if i&val])
    else:
        return None

return None 不是必需的:它是映射到零的标志。

或者如果你想要一个标志列表(在这种情况下,标志可以是任何东西):

def obtain_flag(val):
    if val:
        return [f for f,i in zip(flags,power2()) if i&val]

这给出了:

>>> obtain_flag(6)
'HDDT'
>>> obtain_flag(7)
'HRHDDT'
>>> obtain_flag(0) # returns None, but None is not printed
>>> obtain_flag(1)
'HR'
>>> obtain_flag(2)
'HD'
>>> obtain_flag(3)
'HRHD'
>>> obtain_flag(4)
'DT'

【讨论】:

  • 为什么不使用enumerate1<<n 来避免需要power2 助手?
【解决方案2】:

您可以像这样将标志存储为dict

flags = {1:'HR', 2:'HD', 4:'DT', 8:'FL'}

逐位and你的号码和标志来检索字符串:

def get_flags(num):
    if num:
        return ''.join(flags[x] for x in flags if x & num)
    return None

>>> get_flags(6)
'HDDT'

【讨论】:

  • return None 行是多余的,仍然是 +1
  • 这正是我想要的^^
猜你喜欢
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 2019-12-22
  • 2014-02-12
  • 2020-03-31
  • 2011-03-20
  • 1970-01-01
相关资源
最近更新 更多