列表的切片

3

给定一个限制和一个包含任意数量项的列表列表,我想要截取列表中所有列表项的总数等于限制的部分。

目前我的努力:

lol = [['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s', '0', 'u', 'x']]

def cut_lol(lol, n):
    count = 0
    result = []
    for l in lol:
        if count + len(l) > (n):
            new_len_l = count + len(l) - n
            result.append(l[:new_len_l])
            return result
        result.append(l)
        count += len(l)
    return result

但是这个函数有问题,我看不出来是什么。
例如:
print(cut_lol(lol, 8))
# returns    [['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s', '0', 'u']]
# should be: [['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s']]


print(cut_lol(lol, 4))
# returns    [['a', 'v', '1', 'r'], ['d', 'x', 'b']]
# should be: [['a', 'v', '1', 'r']]


print(cut_lol(lol, 3))
# returns    [['a']]
# should be: [['a', 'v', '1']]

有谁能帮我让这个工作起来吗?谢谢!


它不应该返回空列表吧? - Willem Van Onsem
2个回答

3

只需进行最小更改以使其正常运行:

lol = [['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s', '0', 'u', 'x']]

def cut_lol(lol, n):
    count = 0
    result = []
    for l in lol:
        if count + len(l) > (n):
            new_len_l = n - count
            if new_len_l:
                result.append(l[:new_len_l])
            return result
        result.append(l)
        count += len(l)
    return result

简化版:

lol = [['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s', '0', 'u', 'x']]

def cut_lol(lol, n):
    count = 0
    result = []
    for l in lol:
        to_read = n - count
        if to_read <= 0:
            break
        result.append(l[:to_read])
        count += len(l)
    return result

谢谢您的快速回答! - BetterSaveThanSorry

2
我们可以使用一个 for 循环和条件返回来实现这个功能:
def cut_lol(lol, n):
    result = []
    for li in lol:
        if n <= 0:
            return result
        sli = li[:n]
        result.append(sli)
        n -= len(sli)
    return result

所以在这里,我们迭代 lol 中的子列表 li。每次我们检查剩余元素数量 n 是否已经达到零,在这种情况下,我们返回到目前为止获得的结果。否则,我们附加一个切片版本的子列表,使其最多包含 n 个元素。我们每次递减该数字。
我们可以通过使切片有条件地进行来提高效率:
def cut_lol(lol, n):
    result = []
    for li in lol:
        if n <= 0:
            return result
        <b>sli = li
        if len(sli) > n:
            sli = sli[:n]</b>
        result.append(sli)
        n -= len(sli)
    return result

样例输出:

>>> cut_lol(lol, 0)
[]
>>> cut_lol(lol, 1)
[['a']]
>>> cut_lol(lol, 2)
[['a', 'v']]
>>> cut_lol(lol, 3)
[['a', 'v', '1']]
>>> cut_lol(lol, 4)
[['a', 'v', '1', 'r']]
>>> cut_lol(lol, 5)
[['a', 'v', '1', 'r'], ['d']]
>>> cut_lol(lol, 6)
[['a', 'v', '1', 'r'], ['d', 'x']]
>>> cut_lol(lol, 7)
[['a', 'v', '1', 'r'], ['d', 'x', 'b']]
>>> cut_lol(lol, 8)
[['a', 'v', '1', 'r'], ['d', 'x', 'b'], ['s']]

这也适用于元组和其他可切片的对象(在这种情况下,结果将是这些切片对象的列表)。


谢谢!我选择了你的答案,因为它优雅地利用了Python列表切片的负值,并考虑了性能。 - BetterSaveThanSorry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接