關於python中slicing的探討
1.overview
Python Reference Manual(2016)對slicing的定義如下:
a slicing selects a range of items in a sequence object (e.g. a string, tuple, or list).
slicing 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_slice
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound ::= expression
upper_bound ::= expression
stride ::= expression
There is ambiguity in the formal syntax here: anything that looks like an expression list also looks like a slice, so any subscription can be interpretated as a slicing. Rather than further complicating the syntax, this is disambiguated by difining that in this case the interpretation as a subscription takes priority over the interpretaton as a slicing (this is the case if the slice list contains no proper slice).
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.
2.explanation
a slicing selects a range of items in a sequence object (e.g. a string, tuple, or list).
切片的原材料是序列物件,在python中常見為string, tuple和list,換言之,自定義的類如果是序列物件也可以有切片功能
slicing 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_slice
proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
lower_bound ::= expression
upper_bound ::= expression
stride ::= expression
- 主要語法是[],中間包含一個slice_list;
- slice_list是由逗號分隔開的slice_item組成的;
- slice_item可以是表示式或者是proper_slice;
- proper_slice的結構是"[下限]:[上限]:[步長]";
- 下限、上限和步長都是表示式組成的。
There is ambiguity in the formal syntax here: anything that looks like an expression list also looks like a slice, so any subscription can be interpretated as a slicing. Rather than further complicating the syntax, this is disambiguated by difining that in this case the interpretation as a subscription takes priority over the interpretaton as a slicing (this is the case if the slice list contains no proper slice).
表示式的列表和切片會看起來很像,因為都是中括號中間加入表示式。subscription的定義是“subscription ::= primary "[" expression_list "]"”
為了避免語義複雜化,如果沒有proper_slice,則下標的解析優先於切片。
>>> s = 'hello'
>>> print(s[2]) # 2優先解析為下標index
l
>>> print(s[::-1]) # ::-1解析為切片slice
olleh
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.
primary是mapping object的說法值得商榷,或許sequence object更合適。index使用的是和subscription一樣的_getitem_()方法。如果slice中含有逗號,則key解析為tuple。如果只有一個slice_item,則生成一個slice object,start, stop, step由表示式賦值,預設為None。如果某個bound是負數,那麼這個bound將會轉化為(bound + sequence’s length)。對於Evaluation的結果,如果超出了[0: sequence's length],那麼會使用邊界值替代超出值。
3.lab
自定義一個可以slice的物件,根據定義,只要是序列物件即可。
class T1:
def __getitem__(self, key):
print(key)
>>> t = T1()
>>> t[:-1, ] # slice_item有逗號,解析為一個slice tuple
(slice(None, None, -1),)
>>> t[1:2:3, 4:5:6] # 每個slice_item賦值start, stop, step
(slice(1, 2, 3), slice(4, 5, 6))
使用built-in的list來實現自定義類的slicing:
class T2:
def __init__(self, *args):
self.l = [x for x in args]
def __getitem__(self, key):
print(key)
return self.l[key]
>>> t = T2(1, 2, 3)
>>> print(t[int(2*0.5)]) # slice_item可以是表示式
1
2
>>> print(t[:-1]) # 預設的部分是None
slice(None, -1, None)
[1, 2]
>>> print(t[::-1])
slice(None, None, -1)
[3, 2, 1]
>>> print(t[:-1, ])
list indices must be integers or slices, not tuple
# sequence的slicing不支援逗號分隔的元組,僅支援單個slice的object。T1中的分隔方法在T2中不支援,因為T2的資料型別是list,屬於sequence。
4.example
>>> t = "I am a student."
>>> print(t[2])
a
>>> print(t[-1]) # 負數index相當於index + length,這裡是-1+15=14
.
>>> print(t[2:4]) # 從start開始到stop結束,包括start,不包括stop
am
>>>print(t[:4], t[7:], sep='|') # 預設start則預設從頭開始,預設stop則預設到最後結束,預設step預設正向步長為1
I am|student.
5.take away points
字串倒序很常用:
>>> s = 'hello world'
>>> print(s[::-1])
dlrow olleh
相關文章
- 關於 performSelector 的一些小探討performSelector
- SEO關於探討URL的知識!
- 關於volatile與指令重排序的探討排序
- 關於 Roguelike 的探討,及基於 Roguelike 的新框架框架
- 關於 Xmind 用例線上管理的探討
- iOS 中關於列表滾動流暢方案的一些探討iOS
- python建立elasticsearch索引的探討PythonElasticsearch索引
- 關於 js 物件 轉 字串 和 深拷貝 的 探討JS物件字串
- 關於結構體中指標的一些探討結構體指標
- 中國 GPL 訴訟第一案:關於 GPL 問題的探討
- 關於《以撒的結合》的探討:純善與極惡
- 關於 PHP-fpm master 程式和 worker 職責探討PHPAST
- XAF中XPO與EFCore的探討
- 探討PostgreSQL例項中資料庫之間的關係SQL資料庫
- 【Web Components】關於自定義元件屬性在 Vue 和 React 中不同表現的探討Web元件VueReact
- 技能篇:關於快取資料的一致性探討快取
- TechInsights關於蘋果智慧手錶金屬殼電池的探討蘋果
- Spring 下,關於動態資料來源的事務問題的探討Spring
- 關於vue中image控制元件,onload事件裡,event.target 為null的奇怪問題探討Vue控制元件事件Null
- Promise探討Promise
- 探討系統中?錢的精度問題
- 深入探討:Maven中的物料清單BOMMaven
- MySQL 日誌之 binlog 格式 → 關於 MySQL 預設隔離級別的探討MySql
- 【MySQL經典案例分析】關於資料行溢位由淺至深的探討MySql
- Python從菜鳥到高手:分片(Slicing)Python
- C#中的介面和泛型集合探討C#泛型
- 深入探討Spring Boot中的引數傳遞Spring Boot
- 探討Java中的多執行緒概念 - foojayJava執行緒
- 關聯規則挖掘:Apriori演算法的深度探討演算法
- 深入探討 UndefinedUndefined
- 深入探討HBASE
- OPCUA 探討(一)
- 關於Redis的問題探討(二):Range方法返回的物件是LinkeHashMap以及轉換辦法Redis物件HashMap
- 探討Web開發中的Session儲存與管理WebSession
- 探討.NET Core的未來
- 從實際案例中探討io中的延遲效能的作用
- 關於Python中的日期處理Python
- 基於Kubernetes服務發現機制的探討Non Service