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

时间:2017-02-11 05:35:04

标签: python list list-comprehension

我对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,但似乎无法弄清楚需要什么条件。

3 个答案:

答案 0 :(得分:1)

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

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']

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

最简单的方法是使用某种grouper来提供块。 itertools - 模块提供了这样一个功能:

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']