代码之家  ›  专栏  ›  技术社区  ›  Ahmed Younes

使用列表理解分配给列表[:]

  •  -3
  • Ahmed Younes  · 技术社区  · 6 年前

    从这个答案 https://stackoverflow.com/a/1207461/8074522 我想找出使用

    somelist = [1,2,3,4,5,6,7,8,9]
    somelist = [x for x in somelist if x>4]
    and 
    somelist[:] = [x for x in somelist if x>4]
    

    在他的回答中,他说

    或者,通过指定给slice somelist[:],可以改变现有的 仅包含所需项目的列表:

    “仅包含”<我可以使用分配给somelist而不进行切片。

    那么什么是somelist[:] here?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Valdi_Bo    6 年前

    指令类 somelist = [1,2,3,4,5,6,7,8,9] 创建一个 新建列表 分配 它(整个列表)到您的变量( somelist )

    第二个案例, somelist = [x for x in somelist if x>4] 只是 过滤 . 这个 for 循环将此列表中的每个元素分配给一个临时变量 x .

    然后(在这个循环中) if 检查此(当前)元素是否满足 某些情况下,在您的情况下,它是否大于4。

    只有当它是,这个元素才会被添加到新的数组中,最后 分配给 某个列表 .

    现在有什么区别 普通分配 (只是为了 某个列表 ) 以及 切片分配 (到) somelist[:] )

    想象一下最初 otherList 你创造了你的 某个列表 使用普通分配: somelist = otherList .

    实际上,没有第二个列表被创建,但是 某个列表 可被视为 另一个指向第一个列表的“指针”。

    换句话说,两者都是 其他列表 某个列表 指向 相同的 内部的 对象(在本例中是数组)。

    然后,在代码的后面,如果使用 somelist[:] = ... 你写新内容 到 相同的 内部对象,因此新内容也可以使用 其他列表 (例如在代码的其他部分)。

    但如果你用的是简单的作业( somelist = ... ,然后:

    • 创建了一个 新的 内部对象(数组)和 某个列表 点 就为了它。
    • 这个 古老的 内容仍可见为 其他列表 .

    因此 乔恩沙普 指出,使用哪种选择取决于 您的应用程序真正需要什么。

    在最简单的情况下,如果没有其他变量指向“old” 数组,可以使用纯赋值(imho是一个更自然的选项)和 旧数组(现在没有来自任何其他变量的引用)将是垃圾 收集。

        2
  •  1
  •   Leo K    6 年前

    @乔夏普在评论中给出了简短的回答,但为了清楚地说明这一点:

    分配新列表。丢失对旧列表对象的引用并创建 新的 一:

    >>> lst1 = [[1, 2, 3],[4, 5, 6]]
    >>> lst2 = lst1
    >>> lst1 = [[7,8,9]]
    >>> lst1 is lst2
    False
    >>> lst1
    [[7, 8, 9]]
    >>> lst2
    [[1, 2, 3], [4, 5, 6]]
    

    分配给切片。 替换 列表(或列表的一部分,取决于切片是什么)就位,保持相同的对象。

    >>> lst1 = [[1, 2, 3],[4, 5, 6]]
    >>> lst2 = lst1
    >>> lst1[:] = [[7,8,9]]
    >>> lst1 is lst2
    True
    >>> lst1
    [[7, 8, 9]]
    >>> lst2
    [[7, 8, 9]]