了解列表切片中的否定步骤

时间:2017-01-21 19:05:20

标签: python list slice negative-number

我正在尝试了解以下行为,并欢迎任何参考(特别是官方文档)或评论。

让我们考虑一个清单:

>>> x = [1,2,3,4,5,6]

这可以按预期工作

>>> x[-1:-4:-1] 
[6, 5, 4]

但我很惊讶以下是空的:

>>>  x[0:-4:-1] 
[]

因此,我很惊讶以下不是空的

>>> x[0:-len(x)-1:-1]
> [1]

特别是考虑到

>>> x[0:-len(x):-1] 
[]

还有那个

>>> x[0:-len(x)-1] 
[]

是空的。

3 个答案:

答案 0 :(得分:4)

事实

> x[-1:-4:-1] 
[6, 5, 4]
> x[0:-4:-1] 
[]

不应该让你大吃一惊!很明显,您可以在向后步骤中将列表从最后一个元素切换到倒数第四个元素,但不能从第一个元素中切割。

x[0:i:-1]

i必须为< -len(x)才能解析索引< 0以使结果包含元素。 slice的语法很简单:

x[start:end:step]

表示切片从start开始(此处为0),并在 end之前结束(或由任何否定{{1}引用的索引})。 end解析为-len(x),从0开始到0结尾的切片长度为0,不包含任何元素。但是,0将解析为实际的-len(x)-1,从-1开始生成一段1的长度。

更直观地理解在后向切片中留空0

end

答案 1 :(得分:2)

我被指向了参考实现(对Anonymous Benefactor的仇恨),并发现从那里理解行为是相当简单的。要完成,恕我直言,这种行为是不直观的,但它仍然定义良好,与参考实现相匹配。

两个CPython文件是相关的,即描述list_subscriptPySlice_AdjustIndices的文件。在这种情况下从列表中检索切片时,会调用 list_subscript 。它调用 PySlice_GetIndicesEx ,后者又调用 PySlice_AdjustIndices 。 现在 PySlice_AdjustIndices 包含简单的if / then语句,用于调整索引。最后它返回切片的长度。对我们来说,行

if (*stop < 0) {
    *stop += length;
    if (*stop < 0) {
        *stop = (step < 0) ? -1 : 0;
    }
}

特别重要。调整后,x[0:-len(x)-1:-1]变为x[0:-1:-1],并返回长度1。但是,当x[0:-1:-1]传递给adjust时,它会变为x[0:len(x)-1:-1]长度为0.换句话说,在这种情况下为f(x) != f(f(x))

值得注意的是, PySlice_AdjustIndices 中有以下评论:

/* this is harder to get right than you might think */

最后请注意,python docs中没有描述有关情况的处理。

答案 2 :(得分:-1)

Public Sub PostedLink(ByVal id As String, ByVal link As String)
    Dim query As String = "UPDATE Table SET torf = 1 , link = '" & link & "' WHERE id = '" & id & "';"
    Dim affectedRows As Integer = 0
    Try
        Using con As New SQLiteConnection(connectionString)
            con.Open()
            Using cmd As New SQLiteCommand(con)
                cmd.CommandTimeout = 20
                cmd.CommandText = query
                'Dim dr As SQLiteDataReader
                'dr = cmd.ExecuteReader()
                affectedRows = cmd.ExecuteNonQuery()
            End Using
            con.Close()
        End Using
    Catch ex As Exception
        AddErrors("Updating table", ex.ToString)
    End Try
End Sub

使用-1步从0到2?