有没有办法在 python 中以无循环的十六进制格式打印复杂结构的所有值?

Is there a way to print all values of a complex structure in hexadecimal format without loops, in python?

我有时不得不打印复杂的结构,例如元组列表,比如:

lst = [(101, 102), (103, 104)]
print(lst)
[(101, 102), (103, 104)]

我希望打印格式为十六进制,最好是这样的:

print(lst.hex())
[(0x65, 0x66), (0x67, 0x68)]

如果我有一个简单的列表,I could write:

>>> a_list = range(4)
>>> print '[{}]'.format(', '.join(hex(x) for x in a_list))
[0x0, 0x1, 0x2, 0x3]

所以我假设使用嵌套列表理解或多变量列表理解,我可以做到这一点,我几乎不知道我是怎么想的,我在这里阅读了关于这个主题的几本 Q/A。

那么,有没有一种简单的方法来做到这一点,而不受结构复杂性的影响?

使用列表理解怎么样?

lst = [(101, 102), (103, 104)]
print([(hex(x),hex(y)) for x,y in lst])

输出:

>> [('0x65', '0x66'), ('0x67', '0x68')]

或者您可以使用 NumPy 打印选项:

import numpy as np
lst = [(101, 102), (103, 104)]
np.set_printoptions(formatter={'int':hex})
print(np.array(lst))

使用 Andrew Ryan 的想法,这里是一个依赖于递归而不是迭代的解决方案:

lst = [(101, 102), (103, 104)]


def recursive_convert(l, i=0):
    if type(l) == list:
        x = l.pop(i)
        l.insert(i, recursive_convert(x))
        if i+1 < len(l):
            return recursive_convert(l,i+1)
        return l
    elif type(l) == tuple:
        l = (hex(l[0]), hex(l[1]))
        return l
    


print(recursive_convert(lst))

请注意,这假设了一些事情,例如元组中的元素数量以及列表中数据结构的知识。

输出:

[('0x65', '0x66'), ('0x67', '0x68')]

您可以获得结构的正常字符串表示,并使用正则表达式将所有数字转换为十六进制:

import re
lst = [[(1, 2), (3, 4)], [(5, 6), (7, 8)]]
print(re.sub(r'\d+', lambda match: hex(int(match.group())), str(lst)))

输出:

[[(0x1, 0x2), (0x3, 0x4)], [(0x5, 0x6), (0x7, 0x8)]]

这样做的好处是它完全不依赖于结构。它只是在列表的字符串表示中查找数字,并用它们的十六进制值替换它们。这允许它处理列表、元组和整数的任意组合,例如:

import re
lst = [(1, 2), (3, 4)], [(5, 6), (7, 8)], [[1]], 1234, 1, [(99)]
print(re.sub(r'\d+', lambda match: hex(int(match.group())), str(lst)))

输出:

[[(0x1, 0x2), (0x3, 0x4)], [(0x5, 0x6), (0x7, 0x8)], [[0x1]], 0x4d2, 0x1, [0x63]]