列表理解,如果切片过去列表边界执行此操作



我对python相当陌生,并且在以下代码片段中使用了列表理解:

while offset < len(list)
    s = ['{:04x}'.format(i) for i in list[offset:offset+16]]
    do stuff with s
    offset += 16

该代码段循环遍历list,并以格式化方式将最多 16 个元素添加到 s,然后将 16 添加到偏移值以获得下一个 16,直到看到所有元素。这适用于我的未简化代码,但我想在切片超过列表大小时强加一个占位符,而不是让它停止向s添加元素。我知道我可以用一个完整的 for 循环来做到这一点,但为了保持一行的简洁,我想尝试在理解中做到这一点。我想我需要if/else理解,但似乎无法弄清楚需要什么条件。

您可以将切片块动态填充到固定大小。例如:

while offset < len(l):
    s = ['{:04x}'.format(i) for i in l[offset:offset + 16] + [0] * max(0, offset + 16 - len(l))]
    offset += 16
    # Do something

例如,对于固定大小为 4 时,以下代码:

WIDTH = 4
offset = 0
l = list(range(10))
while offset < len(l):
    s = ['{:04x}'.format(i) for i in
         l[offset:offset + WIDTH] + [0] * max(0, offset + WIDTH - len(l))]
    offset += WIDTH
    print(s)

收益 率:

['0000', '0001', '0002', '0003']
['0004', '0005', '0006', '0007']
['0008', '0009', '0000', '0000']

将切片与包含占位符的列表连接起来 - 因此,当切片结束时,将获取占位符,并将具有所需最终大小的辅助迭代器添加到循环中(range将起作用(,以限制第一部分中生成的项目:

s = ['{:04x}'.format(i) for i, j in in  zip(list[offset:offset+16] + ([placeholder] * 16)  , range(16) ) ]

最简单的方法是使用某种grouper来为您提供块。itertools -module 提供了这样一个函数:

from itertools import zip_longest  # or izip_longest in Python2
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

使用该功能,您可以像这样操作:

lst = list(range(20))
for group in grouper(lst, n=8, fillvalue=0):
    print(['{:04x}'.format(i) for i in group])

产生此输出:

['0000', '0001', '0002', '0003', '0004', '0005', '0006', '0007']
['0008', '0009', '000a', '000b', '000c', '000d', '000e', '000f']
['0010', '0011', '0012', '0013', '0000', '0000', '0000', '0000']

最新更新