【问题标题】:How to cut elements from list of integer如何从整数列表中剪切元素
【发布时间】:2013-09-27 03:03:23
【问题描述】:

如果我有一个整数列表

    x=[0, 0, 119, 101, 108, 108, 99, 111, 109]

我想从左边剪掉 2 个元素

    x=[119, 101, 108, 108, 99, 111, 109]

我该怎么办?

【问题讨论】:

    标签: python list integer


    【解决方案1】:

    使用Python's slice notation:

    >>> x = [0, 0, 119, 101, 108, 108, 99, 111, 109]
    >>> x = x[2:]
    >>> x
    [119, 101, 108, 108, 99, 111, 109]
    

    这会获取从第三项到列表末尾的每个元素,我们只需将 x 设为其值。

    【讨论】:

    • 我建议对就地分配进行简短描述,作为您答案的一部分:x[:] = x[2:]。否则,您将创建一个副本,而 IRL 可能是不可取的。
    • @kojiro 不过在这种情况下有关系吗?我看不出有什么问题:3
    • 在这种情况下没关系,但 OP 和未来的读者可能不知道。我只是建议对答案稍作改进。
    • @kojiro 我仍然不明白为什么这是一个问题。它会出现在哪里?
    • @Haidro 如果您对列表有多个引用并且您希望它们相同,则可能会出现。 gist.github.com/kojiromike/6655738
    【解决方案2】:

    不不不不不

    抱歉,我认为 Haidro 的解决方案不好,因为执行了不必要的重新分配。

    见:

    x = [0, 0, 119, 101, 108, 108, 99, 111, 109]
    print id(x)
    x = x[2:]
    print id(x)
    
    print
    
    y = [0, 0, 119, 101, 108, 108, 99, 111, 109, 1003]
    print id(y)
    y[:2] = []
    print id(y)
    

    结果

    18713576
    18739528
    
    18711736
    18711736
    

    编辑 1

    显示x = x[2:] 导致问题的示例:

    x = [0, 0, 119, 101, 108, 108, 99, 111, 109, 1003]
    print id(x),x
    
    gen = ((i,a+100) for i,a in enumerate(x))
    
    for u in xrange(4):
        print '%d %d' % gen.next()
    
    x = x[2:]
    print 'x = x[2:]\n',id(x),x
    
    for u in xrange(4):
        print '%d %d' % gen.next()
    
    print '--------------------------'
    
    y = [0, 0, 119, 101, 108, 108, 99, 111, 109, 1003]
    print id(y),y
    
    gen = ((i,b+100) for i,b in enumerate(y))
    
    for u in xrange(4):
        print '%d %d' % gen.next()
    
    y[:2] = []
    print 'y[:2] = []\n',id(y),y
    
    for u in xrange(4):
        print '%d %d' % gen.next()
    

    结果

    18713576 [0, 0, 119, 101, 108, 108, 99, 111, 109, 1003]
    0 100
    1 100
    2 219
    3 201
    x = x[2:]
    18711736 [119, 101, 108, 108, 99, 111, 109, 1003]
    4 208
    5 208
    6 199
    7 211
    --------------------------
    18740128 [0, 0, 119, 101, 108, 108, 99, 111, 109, 1003]
    0 100
    1 100
    2 219
    3 201
    y[:2] = []
    18740128 [119, 101, 108, 108, 99, 111, 109, 1003]
    4 199
    5 211
    6 209
    7 1103
    

    在第一种情况下( x = x[2:] ),x 被重新分配给另一个对象。但是在重新分配之前创建的生成器仍然使用相同的列表对象来生成元素。这可能是某些代码中的问题。
    但确实,其他代码在其他情况下也可能是一个问题。
    我的意思是,我们绝对不会受到x = x[2:] 的保护,从而导致问题。

    编辑 2

    z[:] = z[2:]y[:2] = [] 明显不同:

    import dis
    
    print 'y[:2] = []'
    def f(z):
        y[:2] = []
    dis.dis(f)
    print '====================='
    print 'z[:] = z[2:]'
    def f(z):
        z[:] = z[2:]
    dis.dis(f)
    

    结果

    y[:2] = []
      7           0 BUILD_LIST               0
                  3 LOAD_GLOBAL              0 (y)
                  6 LOAD_CONST               1 (2)
                  9 STORE_SLICE+2       
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE        
    =====================
    z[:] = z[2:]
     12           0 LOAD_FAST                0 (z)
                  3 LOAD_CONST               1 (2)
                  6 SLICE+1             
                  7 LOAD_FAST                0 (z)
                 10 STORE_SLICE+0       
                 11 LOAD_CONST               0 (None)
                 14 RETURN_VALUE  
    

    【讨论】:

    • y[:2] = [] 行中,您很可能打算输入y[:] = y[2:]。在当前状态下,您的答案并未解决原始问题,因为它只是对 Haidro 答案的批评(因此应该在评论中)。
    • @ShashankGupta 我不知道你说的“可能是什么意思”是什么意思。我看到的是这两个指令的反汇编是不同的,请参阅我的第二次编辑。顺便说一句,你是对我的答案投反对票的人吗?
    • 是的,我确实否决了您的答案,因为它甚至没有解决问题。您刚刚发表这篇文章是为了批评 Haidro 的回答,我觉得这有点愚蠢。当我说“可能的意思”时,我指的是您似乎根本没有与 OP 交谈,我觉得您应该将这个“答案”作为评论留下。
    • @ShashankGupta 我无法想象你怎么能说我没有解决这个问题。在问题中,OP 说 I'd like to cut 2 elements from left :这正是我的代码所做的。
    • 如果您首先回答以下问题,我会赞成您的回答:x[:2] = [],然后解释为什么这种形式是最好的。
    猜你喜欢
    • 2015-08-25
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多