在python中,按一定长度将列表列表组合到另一个列表列表中

在python中,按一定长度将列表列表组合到另一个列表列表中,python,Python,我正在寻找一个单班轮转换 [[1], [1, 1], [1, 1, 1], [1], [1], [1], [1, 1, 1, 1]] 到 其中,算法将列表合并到某个阈值长度 我现在有这个 batched = [] batch = [] for l in lists: batch.extend(l) if len(batch) > threshold: batched.append(batch) batch = [] 这是一个丑陋的一行这不

我正在寻找一个单班轮转换

[[1], [1, 1], [1, 1, 1], [1], [1], [1], [1, 1, 1, 1]]

其中,算法将列表合并到某个阈值长度

我现在有这个

batched = []
batch = []
for l in lists:
    batch.extend(l)
    if len(batch) > threshold:
        batched.append(batch)
        batch = []

这是一个丑陋的一行这不完全是你想要的(非常接近),但也许它会让你知道如何接近它

arr = [[1], [1, 1], [1, 1, 1], [1], [1], [1], [1, 1, 1, 1]]

threshold = 4

[[x for y in arr for x in y][i:i+threshold] 
     for i, _ in enumerate([x for y in arr for x in y])
       if i % threshold == 0]

Out[31]:
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1]]

这可能不太理想,但这将是我的尝试。其思想是将列表与链接在一起,然后使用从链中拉出并附加一个新列表,直到无法再添加为止。不可否认,它不是一条直线

from itertools import chain, islice
def grouper(n, li):
    it = chain(*li)
    out_l = []
    while True:
        chunk = list(islice(it, n))
        if len(chunk) < n:
            if chunk:
                out_l[-1] += chunk
            return out_l
        out_l.append(chunk)

破解它只是因为我很固执。这真的很难看,效率也很低,也许有更干净的方法,但即使有,也不值得

a = [[1], [1, 1], [1, 1, 1], [2], [1], [1], [1, 1, 1, 1]]

b = [[[item for sublist in a for item in sublist][x+(y*3)] for x in range(1,4)] for y in range(0, (len([i for j in a for i in j])/3))]
编辑:因为我在Python2.7中进行了测试,所以忽略了除法在Python3中的工作方式不同这一事实。感谢@nexus66指出了一个修改(这只会让它变得更长!)


您最初的实现没有问题,但如果您坚持使用oneliner,则有一个丑陋的选项:

from itertools import accumulate, chain, groupby

THRESHOLD = 3
l = [[1], [1, 1], [1, 1, 1], [1], [1], [1], [1, 1, 1, 1]]
res = [[y for x in g for y in x[1]]
       for k, g in groupby(zip(chain([0], accumulate(len(x) for x in l)), l),
                           lambda x: x[0] // THRESHOLD)]
print(res)
输出:

[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]
其思想是生成
(到目前为止的项目计数,子列表)
元组列表,并通过将计数除以
阈值对它们进行分组

>>> temp = list(zip(chain([0], accumulate(len(x) for x in l)), l))
>>> temp
[(0, [1]), (1, [1, 1]), (3, [1, 1, 1]), (6, [1]), (7, [1]), (8, [1]), (9, [1, 1, 1, 1])]
>>> groups = [list(g) for k, g in groupby(temp, lambda x: x[0] // THRESHOLD)]
>>> groups
[[(0, [1]), (1, [1, 1])], [(3, [1, 1, 1])], [(6, [1]), (7, [1]), (8, [1])], [(9, [1, 1, 1, 1])]]
>>> [[y for x in g for y in x[1]] for g in groups]
[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]

我感谢所有的帮助,并且我了解到一行程序对于这个问题不是最好的,因为它丑陋、不可读,而且可能效率低下。也就是说,我确实提出了这一点,这似乎是从一个不同的稍微干净的方法工作

>>> from functools import reduce
>>> l = [[1], [2, 3], [4, 5, 6], [7], [8], [9], [10, 11, 12, 13]]
>>> t = 3
>>> b = reduce(lambda p, n: p[:-1] + [p[-1] + n] if len(p[-1]) + len(n) <= t or not p[-1] else p + [n], l, [[]])
>>> b
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12, 13]]
>>从functools导入reduce
>>>l=[[1]、[2,3]、[4,5,6]、[7]、[8]、[9]、[10,11,12,13]]
>>>t=3
>>>b=减小(λp,n:p[:-1]+[p[-1]+n]如果len(p[-1])+len(n)>>b
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12, 13]]

这可能是一个很好的问题。问题是什么?你的尝试似乎没有任何问题。@Jean-Françoisfare接受了挑战,尽管它看起来已经很难看。我不知道为什么这个问题会被否决,关于python一行程序的问题似乎很常见,这里还有一个例子,@shane-它被否决了,因为它没有显示任何研究工作来解决实际问题(而且它也不太可能有用)。您的代码产生了一个异常。您可以将它更新为
[[[a for sublist in a for item in a for item in sublist][x+(y*3)]范围内的x(1,4)]范围内的y(0,int((len a([i for j in a for i in j])/3))]
@nexus66什么异常?我没有得到任何索引错误。@nexus66两种方法在2.7中给了我相同的答案,我想知道这是否是Python 3除法?它产生了这个异常
TypeError:“float”对象不能在Python3@nexus66我刚刚意识到,列表的扁平化最终会失去初始结构,因此在最后一个元素上缺少阈值。这很令人沮丧。
[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]
>>> temp = list(zip(chain([0], accumulate(len(x) for x in l)), l))
>>> temp
[(0, [1]), (1, [1, 1]), (3, [1, 1, 1]), (6, [1]), (7, [1]), (8, [1]), (9, [1, 1, 1, 1])]
>>> groups = [list(g) for k, g in groupby(temp, lambda x: x[0] // THRESHOLD)]
>>> groups
[[(0, [1]), (1, [1, 1])], [(3, [1, 1, 1])], [(6, [1]), (7, [1]), (8, [1])], [(9, [1, 1, 1, 1])]]
>>> [[y for x in g for y in x[1]] for g in groups]
[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1, 1]]
>>> from functools import reduce
>>> l = [[1], [2, 3], [4, 5, 6], [7], [8], [9], [10, 11, 12, 13]]
>>> t = 3
>>> b = reduce(lambda p, n: p[:-1] + [p[-1] + n] if len(p[-1]) + len(n) <= t or not p[-1] else p + [n], l, [[]])
>>> b
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12, 13]]