gpt4 book ai didi

python - 将键-长度-值 (KLV) 字符串拆分为键、长度、值的小列表

转载 作者:行者123 更新时间:2023-12-01 07:55:31 29 4
gpt4 key购买 nike

将 KLV 字符串拆分为键、长度、值作为元素的列表/元组的更有效方法是什么?

为了添加一点背景,前 3 位数字作为键,接下来的 2 位表示值的长度。
我已经能够使用以下代码解决该问题。但我不认为我的代码和逻辑是完成任务的最有效方法。因此,我很想听听其他意见,以便我能变得更好。

result = []

def klv_split(ss):
while True:
group1 = ss[:3]
group2 = ss[3:5]
print(group2)
group3 = ss[5 : 5 + int(group2)]
result.append([group1, group2, group3])
try:
klv_split(ss[5 + int(group2) :])
except ValueError:
break
break

return result


klv_string = "0021571583400000026400412000000000200026047299049000850025003ADV25110Blahbleble25304677225400255002560204"
klv_split(klv_string)
print(result)

预期输出是一个包含键长度值的小列表,如下所示。

[['002', '15', '715834000000264'], ['004', '12', '000000000200'], ['026', '04', '7299'], ['049', '00', ''], ['085', '00', ''], ['250', '03', 'ADV'], [
'251', '10', 'Blahbleble'], ['253', '04', '6772'], ['254', '00', ''], ['255', '00', ''], ['256', '02', '04']]

最佳答案

其他答案创建了递归函数的迭代版本。从 Python does not optimize tail call recursion 开始会更快.

我将重点讨论您有一个巨大的二进制文件需要解析的情况:

>>> def klvs(f):
... while True:
... k = f.read(3)
... if not k:
... return
...
... k_length = f.read(2)
... assert len(k_length) == 2
... k_length = int(k_length)
... value = f.read(k_length)
... assert len(value) == k_length
... yield (k, k_length, value)
...

创建迭代器更方便(尽管可能不会更快)。我使用了字节,因为这是您通常获得的 klv 数据:

>>> klv_bytes = b"0021571583400000026400412000000000200026047299049000850025003ADV25110Blahbleble25304677225400255002560204"
>>> import io
>>> f = io.BytesIO(klv_bytes)
>>> list(klvs(f))
[(b'002', 15, b'715834000000264'), (b'004', 12, b'000000000200'), (b'026', 4, b'7299'), (b'049', 0, b''), (b'085', 0, b''), (b'250', 3, b'ADV'), (b'251', 10, b'Blahbleble'), (b'253', 4, b'6772'), (b'254', 0, b''), (b'255', 0, b''), (b'256', 2, b'04')]

您可能希望通过键或索引获取元素而不创建所有元组:

>>> import os
>>> def get(f, to_search):
... i = 0
... while True:
... k = f.read(3)
... if not k:
... return None
...
... k_length = f.read(2)
... assert len(k_length) == 2
... k_length = int(k_length)
... if to_search(i, k):
... value = f.read(k_length)
... assert len(value) == k_length
... return (k, k_length, value)
... else:
... f.seek(k_length, os.SEEK_CUR)
... i += 1
...
>>> f = io.BytesIO(klv_bytes)
>>> get(f, lambda _, k: k==b"004")
(b'004', 12, b'000000000200')
>>> f = io.BytesIO(klv_bytes)
>>> get(f, lambda _, k: k=="foo") is None
True
>>> f = io.BytesIO(klv_bytes)
>>> get(f, lambda i, _: i==10)
(b'256', 2, b'04')
>>> f = io.BytesIO(klv_bytes)
>>> get(f, lambda i, _: i==11) is None
True

请注意,get 函数的时间复杂度为 O(n),如果查找多个元素,则列表或字典的创建速度会更快。

关于python - 将键-长度-值 (KLV) 字符串拆分为键、长度、值的小列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56002195/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com