使用特定规则迭代列表

时间:2016-12-27 15:11:05

标签: python list

我正在编写一个分析DHCP数据包的程序,并遇到了选项43(供应商特定信息)。这更像是一个编程问题,在技术上与网络和DHCP相关性较小,因此我将其标记为python。

根据RFC 2132(第19页),选项43的结构如下:

 Code   Len   Data item        Code   Len   Data item       Code
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|  T1 |  n  |  d1 |  d2 | ... |  T2 |  n  |  D1 |  D2 | ... | ... |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+

当翻译成python'bytes'对象时,它看起来应该是这样的:

[T1, n, d1, d2, ..., T2, n, D1, D2, ...]

其中n是数据项(Dn)的长度。

理想情况下,我希望迭代此字节对象并将每个数据项的代码保存为键,并将其映射到相应的数据项值。 IE:

{T1: [d1, d2, d3], T2: [D1, D2, D3]}

例如:

[0, 1, 2, 1, 2, 5, 6, 3, 4, 9, 10, 11, 12]

应该转化为:

{0: [2], 1: [5,6], 3: [9, 10, 11, 12]}

在python中有没有正确的方法呢?

编辑:还有,是的。代码(Tn)是唯一的。

4 个答案:

答案 0 :(得分:3)

使用递归函数:

trans_dict = {}
def translate(lst, trans_dict):
    if(len(lst) == 0):
        return
    else:   ​
        trans_dict[lst[0]] = lst[2:(2+lst[1])]        # the first element will be the key, 
                                                      # the value starts from the third 
                                                      # element with length of the second element
        translate(lst[(2+lst[1]):], trans_dict)

translate(lst, trans_dict)

trans_dict
# {0: [2], 1: [5, 6], 3: [9, 10, 11, 12]}

答案 1 :(得分:2)

我的解决方案:

packets = [0, 1, 2, 1, 2, 5, 6, 3, 4, 9, 10, 11, 12]

pos_head = 0
len_data = len(packets)

d = dict()

while pos_head  < len_data:
    key = packets[pos_head]
    if pos_head +2 > len_data:
        break
    size = packets[pos_head+1]
    if pos_head + 2 + size > len_data:
        break
    data = packets[pos_head+2: pos_head+2 + size]
    pos_head += 2 + size
    d[key] = data

print(d)

输出:

{0: [2], 1: [5, 6], 3: [9, 10, 11, 12]}

观察:T1,T2,...,Tn不应重复。

答案 2 :(得分:2)

您还可以将for循环与迭代器结合使用。外部for循环将循环遍历T的所有值,而在循环内调用next会移除nd1,...,列表中的dn

def parse(data):
    iterator = iter(data)
    d = {}
    for t in iterator:
        n = next(iterator)
        d[t] = [next(iterator) for _ in range(n)]
    return d

你甚至可以把所有这些都放到一个词典理解中......

def parse(data):
    it = iter(data)
    return {t: [next(it) for _ in range(next(it))] for t in it}

示例:

>>> data = [0, 1, 2, 1, 2, 5, 6, 3, 4, 9, 10, 11, 12]
>>> parse(data)
{0: [2], 1: [5, 6], 3: [9, 10, 11, 12]}

答案 3 :(得分:1)

使用嵌套的whilefor循环,我的解决方案是(T1Tn应该是唯一的,因为它们是生成的字典键):

my_list = [0, 1, 2, 1, 2, 5, 6, 3, 4, 9, 10, 11, 12]

res = {}
i = 0

while i < len(my_list):
    num = my_list[i+1]
    for j in range(i+2, i+2+num):
        if i in res:
            res[i].append(my_list[j])
        else:
            res[i] = [my_list[j]]
    i += 2 + num

<强>输出:

>>> res
{0: [2], 3: [5, 6], 7: [9, 10, 11, 12]}