将十六进制函数装饰以填充零

115

我写了这个简单的函数:

def padded_hex(i, l):
    given_int = i
    given_len = l

    hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
    num_hex_chars = len(hex_result)
    extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..

    return ('0x' + hex_result if num_hex_chars == given_len else
            '?' * given_len if num_hex_chars > given_len else
            '0x' + extra_zeros + hex_result if num_hex_chars < given_len else
            None)

例子:

padded_hex(42,4) # result '0x002a'
hex(15) # result '0xf'
padded_hex(15,1) # result '0xf'

虽然对我来说这很清楚,并且符合我的用例(一个简单打印机的简单测试工具),但我无法不思考还有很多改进的空间,这可以被压缩为更简洁的东西。

还有哪些方法可以解决这个问题呢?

9个回答

266

从Python 3.6开始,您可以:

>>> value = 42
>>> padding = 6
>>> f"{value:#0{padding}x}"
'0x002a'

对于较旧版本的Python,请使用 .format() 字符串方法:

>>> "{0:#0{1}x}".format(42,6)
'0x002a'

解释:

{   # Format identifier
0:  # first parameter
#   # use "0x" prefix
0   # fill with zeroes
{1} # to a length of n characters (including 0x), defined by the second parameter
x   # hexadecimal number, using lowercase letters for a-f
}   # End of format identifier

如果您想要字母十六进制数字大写,但前缀为小写的“x”,则需要进行一些变通:
>>> '0x{0:0{1}X}'.format(42,4)
'0x002A'

在Python 3.6中,是否可以将此内容编写为格式化字符串? - Richard Neumann
Python 真的喜欢把事情搞复杂。 - user7082181
我可以使用这种格式解决方案获得小写的 'x' 和大写的十六进制数,例如 0x002A 吗? - Katu
1
@Katu:你可以使用 f"{value:#0{padding}X}".replace("X","x") - Tim Pietzcker
抱歉...这里的所有内容都不适用于负数... 请尝试使用以下代码:val = 42 nbits = 16 "{:0>4s}".format(hex((val + (1 << nbits)) % (1 << nbits))[2:]).upper() - karelv
显示剩余2条评论

37

这样怎么样:

print '0x%04x' % 42

11
使用 * 传递宽度:'0x%0*x' % (4,42),其中4是宽度,42是要格式化的数字。 - Ashwini Chaudhary

37

如果您不需要处理负数,可以执行

"{:02x}".format(7)   # '07'
"{:02x}".format(27)  # '1b'

.format() 中,

  • : 是第一个参数 {}格式规范 的起点
  • 02 表示“从左侧用 0 填充输入,直到长度为 2
  • x 表示“使用小写字母十六进制格式化”

您也可以使用 f-strings 来实现此操作:

f"{7:02x}"   # '07'
f"{27:02x}"  # '1b'

20

如果只是为了填充前导零,可以尝试使用zfill函数。

'0x' + hex(42)[2:].zfill(4) #'0x002a'

7

使用*传递宽度,X表示大写。

print '0x%0*X' % (4,42) # '0x002A'

根据 georgAshwini Chaudhary 的建议


使用 * 传递宽度的原因是什么? - tartaruga_casco_mole
3
@RafaelJ 为了使其通用化,不要将其硬编码。 - GabrielOshiro

5

如果您想保留前缀十六进制表示法0x,您也可以尝试使用Python3的f-strings方法。

    f'0x{10:02x}' # 0x0a

2

没有一个答案能够很好地处理负数...
尝试这个:

val = 42
nbits = 16
'{:04X}'.format(val & ((1 << nbits)-1))

enter image description here


'{:0{}X}'.format(val & ((1 << nbits)-1), int((nbits+3)/4)) 将设置正确的宽度。 - karelv

1

假设您想在十六进制数字中使用前导零,例如您想要7位数来写入您的十六进制数字,您可以这样做:

hexnum = 0xfff
str_hex =  hex(hexnum).rstrip("L").lstrip("0x") or "0"
'0'* (7 - len(str_hexnum)) + str_hexnum

这将会得到如下结果:
'0000fff'

1
'%0*x' % (7,0xfff) - jon

1

这将给你一个随机的十六进制字符串 [000001 - FFFFFF]:

# !/usr/bin/python39
import random

f'{random.randint(1, 16777215):06x}'.upper()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接