有没有办法在 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]]
我有时不得不打印复杂的结构,例如元组列表,比如:
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]]