Python 如何使用 map() 将列表拆分为子列表?

3 投票
1 回答
1263 浏览
提问于 2025-04-17 14:01

我有一个函数,可以根据长度把可迭代的对象分成几个小列表,还可以设置填充值和填充的方向:

def split(v,size,fill=0,direction='right'):
    if size == 0: return []
    lenv = len(v)
    count = lenv/size
    remainder = lenv%size
    result = []
    for i in range(0,lenv-remainder,size):
            result.append(v[i:i+size])
    if remainder > 0:
            if direction == 'right':
                    result.append(v[count*size:] + [fill] * (size-remainder))
            else:
                    result.append([fill] * (size-remainder) + v[count*size:])
    return result

因为我喜欢用一行代码来写,所以我想用map来重写这个函数,但我不太明白怎么做。目前我写成这样:

def j1(a,b): 
        return a + b 

def j2(a,b): 
        return b 

def split2(v,size,fill=0): 
        map(j1,(x for x in map(j2,v))) 

我完全不知道该怎么做。有没有什么提示?

1 个回答

6

我觉得你想得有点多。这个问题其实可以用grouper 这个方法来简单解决,而且不需要用到 map

def split1(v,size,fill=0,direction='right'):
    result = list(izip_longest(*[iter(l)]*size, fillvalue=fill))
    if direction == 'left':
        result[-1] = result[-1][::-1]
    return result

解释:

  • iter:这个函数可以把一个序列变成可迭代的对象。可迭代对象可以自己消耗,只有一个方法 next,它会返回可迭代对象中的下一个元素,从左到右取。
  • [iter(l)]*size:创建一个包含 size 个可迭代对象的列表。
  • * (克林星):这个符号用来展开一个列表或元组。
  • izip_longest:把元素进行转置。对于较短的序列,会用填充值来补齐。
  • result[-1] = result[-1][::-1]:如果方向是 left,就把最后的序列反转。

另外一种常见的解决方案是不使用 grouper:

def split2(v,size,fill=0,direction='right'):
    result = [v[i:i+size] for i in range(0,len(v),size)]
    result[-1] = result[-1] + [fill] * (size - len(result[-1]))
    if direction == 'left':
        result[-1] = result[-1][::-1]
    return result

解释:

  • 使用了 Python 的扩展切片。序列切片的语法是 [start: end: stride]
  • Python 的 Range 在 Py2.x 中返回一个列表,在 Py 3.x 中返回一个范围对象,作为一个序列/可迭代对象,从 start 开始,到 end 结束,每次步进 stride 个元素。这类似于 (for int i = start; i < stop; i+= stride)
  • [fill] * (size - len(result[-1])):生成 (size - len(result[-1]))fill 元素,作为一个列表。如果 (size - len(result[-1])) 小于等于 0,就生成一个空列表。
  • result[-1] = result[-1] + [fill] * (size - len(result[-1])) - 用填充值更新最后的序列。
  • result[-1] = result[-1][::-1]:如果方向是 left,就把最后的序列反转。

撰写回答