標籤:

python中字元串 s[ : -1]是什麼意思?


咳,題主這是蠢萌你們不要黑他!

=======假正經的分割線=======

這幾天在刷Python Language Reference,筆者將從syntax與data model的角度解析解析一下s[:-1],權當練手。本文可能不適合初學者閱讀。

從Expression的角度來看,s[:-1]是一個slicing,下面是文檔中的定義:

A slicing selects a range of items in a sequence object (e.g., a string, tuple
or list). Slicings may be used as expressions or as targets in assignment or
del statements. The syntax for a slicing:

slicing ::= primary "[" slice_list "]"
slice_list ::= slice_item ("," slice_item)* [","]
slice_item ::= expression | proper_sliceproper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound ::= expressionupper_bound ::= expressionstride ::= expression

需要注意的是,slicing與subscription是有歧義的,為了解決這個問題,

in this case the interpretation as a subscription
takes priority over the interpretation as a slicing

而事實上,從data model的角度來說,subscription與slicing調用的是同一組的object method,即為:

  • object.__getitem__(self, key)
  • object.__setitem__(self, key)
  • object.__delitem__(self, key)

這三個method分別對應reference/assignment/deletion操作。

下面繼續分析slicing的semantics,其文檔是這麼定義的:

The semantics for a slicing are as follows. The primary must evaluate to a
mapping object, and it is indexed (using the same __getitem__() method as
normal subscription) with a key that is constructed from the slice list, as
follows. If the slice list contains at least one comma, the key is a tuple
containing the conversion of the slice items; otherwise, the conversion of the
lone slice item is the key. The conversion of a slice item that is an
expression is that expression. The conversion of a proper slice is a slice
object
(see section The standard type hierarchy) whose start,
stop and step attributes are the values of the
expressions given as lower bound, upper bound and stride, respectively,
substituting None for missing expressions.

(需要關注的部分已加粗

首先,文檔中提到了「The primary must evaluate to a
mapping object」,其實這裡文檔有點小bug。在Python的data model中,built-in mapping object只有一種,那就是dict,而dict是不支持slicing操作的。筆者認為這一句應該改為「The primary must evaluate to a
sequence object」。

其次,請注意slice_list的語法定義:

slice_list ::= slice_item ("," slice_item)* [","]

當slice_list中只有一個slice_item的時候,如a[:-1],傳入的argument(如「:-1」)會被用於生成一個slice object,其更多信息請看2. Built-in Functions。

當slice_list中出現一個以上逗號的時候,如a[1:2:3, ::-1],傳入的argument會被用於生成一個包含slice object的tuple。這裡的語法與parenthesized form的語法是一致的:

A parenthesized form is an optional expression list enclosed in parentheses:

parenth_form ::= "(" [expression_list] ")"

A parenthesized expression list yields whatever that expression list yields: if
the list contains at least one comma, it yields a tuple; otherwise, it yields
the single expression
that makes up the expression list.

下面是一個示例:

&>&>&> class Test:
... def __getitem__(self, key):
... print(key)
...
&>&>&> t = Test()
&>&>&> t[:-1]
slice(None, -1, None)
&>&>&> t[::-1,]
(slice(None, None, -1),)
&>&>&> t[1:2:3, 4:5:6]
(slice(1, 2, 3), slice(4, 5, 6))

需要注意的是,sequence的slicing操作不支持slice_list with a comma,僅支持傳入單個slice object。假設a是一個built-in sequence instance,a[::-1,]、a[1:2:3, 4:5:6]等操作是不合法的。

需要注意的是,在完成primary evaluation、生成slice object之前,有一步較為重要的工作。為了描述這一步工作,先引一段文檔。下面文字摘自assignment statment:

...

If the target is a slicing: The primary expression in the reference is
evaluated. It should yield a mutable sequence object (such as a list). The
assigned object should be a sequence object of the same type. Next, the lower
and upper bound expressions are evaluated, insofar they are present; defaults
are zero and the sequence』s length.
The bounds should evaluate to integers.
If either bound is negative, the sequence』s length is added to it. The
resulting bounds are clipped to lie between zero and the sequence』s length,
inclusive. Finally, the sequence object is asked to replace the slice with
the items of the assigned sequence. The length of the slice may be different
from the length of the assigned sequence, thus changing the length of the
target sequence, if the object allows it.

上文對assignment statment中LHS為slicing of sequence object的情況進行了說明,以上說明對於reference與deletion也是適用的。讓我們回顧以下slice item的語法:

proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]

按照上面的說明,第一步是對lower_bound與upper_bound進行evaluate,如果缺失則採用默認值。如果某個bound是負數,那麼這個bound將會轉化為(bound + sequence』s length)。對於Evaluation的結果,如果超出了[0: sequence"s length],那麼會使用邊界值替代超出值。以下為示例代碼:

&>&>&> *a, = range(10)
&>&>&> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
&>&>&> a[1:100]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

對於built-in sequence,slicing操作有如下通俗易懂的解釋

Sequences also support slicing: a[i:j] selects all items with index k such
that i &<= k &< j
. When used as an expression, a slice is a
sequence of the same type. This implies that the index set is renumbered so
that it starts at 0.

Some sequences also support 「extended slicing」 with a third 「step」 parameter:
a[i:j:k] selects all items of a with index x where x = i + n*k, n
&>= 0 and i &<= x &< j
.

以上內容應該足以應付題主有關slicing的任何疑惑了。


如果s是一個string,那就是取第一個到倒數第一個字元。

你真的可以親手試試。。。


python裡面的索引的特徵是包含起點,但是不包含結束的索引值,-1表示最後一個元素,但是-1是結尾的index,所以含義就是取原始數據的除最後一個元素之外的值


In [12]: l = list(range(10))

In [13]: l

Out[13]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [16]: l[:-1]

Out[16]: [0, 1, 2, 3, 4, 5, 6, 7, 8]


-n 就是從後往前倒數n個的意思


就是將 s 字元串中倒數第一個字元刪除, -2 就是將s 字元串中倒數後兩個字元刪除 ;

常用在從文本讀入數據的時候消除換行符的影響

s="hello world
"

print s[:-1]

列印 hello world

但是 s 中的
是不會被刪除的,僅僅是截取 s 中刪除了最後一個字元的子串進行返回給接受之


有等答案的時間早就試出來了。


如果題主這麼不愛思考和動手的話。

python不是和你啊。。。。

或者說coding不適合你啊

可恥的匿了

————————————————————————

題主補充了ta其實是想知道原因,那麼本人簡單解釋一下吧,我也不是很精通python,剛好知道這個。

string後面跟的[]裡面是index,表示的是對string中字元的指向,比如[0:n]表示string的中第一個到第n-1個字元,是用0來表示第一個字元的位置。

如果不寫開頭或結尾,就默認從頭開始,或直到最後。例如[:3]其實就是[0:3],就是[0],[1],[2]這三個;[3:]則代表第四個到最後一個。

然後如果index中時負數,則表示從後往前算,倒著數。

希望我說明白了


Strings


孩子,告訴你一個網站,叫做http://StackOverflow.com


推薦閱讀:

為什麼用pycharm在同目錄下import,pycharm會報錯,但是實際可以運行?
不同的語言中多進程和多線程具體的原理是什麼?
為什麼優礦的策略跑起來都很成功,是因為哪些因素沒有考慮到?
怎麼用 Python 編寫程序計算字元串中某個字元的個數?
使用anaconda以後再要使用不在conda環境中的包,要怎麼安裝?

TAG:Python |