字符串與字節
python2中用str表示字節字符串,這種類型現在在Python3中用bytes對象來處理,明確區分字符串與字節
python3中只有一種能夠保存文本信息的數據類型,就是str,它是不可變序列,保存的是Unicode碼位
bytes以及可變的bytearray與str不同,只能用字節作為序列值,即0<=x<=256范圍內的整數。例如
>>>print(bytes([102,111,111])) b'foo'
對於bytes和bytearray,在轉換為另一種序列類型(如list或tuple)時可以顯示其本來面目:例如:
>>>list(b'foo bar') [102,111,111,32,98,97,114] >>>tuple(b'foo bar') (102,111,111,32,98,97,114)
從python3開始,所有沒有前綴的字符串都是Unicode。因此,所有用單引號,雙引號或成組的3個引號包圍且沒有前綴的值都表示str數據類型:
>>>type("some string") <class 'str'>
在python2中,Unicode需要有前綴(例如u"some string")。從python3.3開始,為保證向后兼容,仍然支持這個前綴,但它在python3中沒有任何語法上的意義。
字節的明確語法:字節也被單引號,雙引號或三引號包圍,但必須有一個b或B前綴。
關於pytho字符串編碼與解碼參考: https://blog.csdn.net/trochiluses/article/details/16825269
字符串拼接
python中字符串是不可變的,拼接任意多個字符串時在內存中會產生一個新的序列對象:比如
s="" for substring in substrings: s += substring
字符串s通過多次拼接來創建一個新字符串,但是這中創建方式效率極低。幸好python為我們提供了str.join()方法。它接受一個可迭代字符串為參數。因為它是一個方法,實際調用時利用空字符串來調用,參數為需要拼接的迭代字符串
s="".join(substrings)
join方法還可以在需要合並的多個字符串之間插入分隔符
','.join(['a','b','c','d']) 'a,b,c,d'
雖然join方法速度更快,但並不是所有需要拼接字符串的情況下都使用該方法。在下面幾種情況下,join的性能可能還不如利用加法的普通拼接
- 字符串的數量很少,而且已經存在在某個可迭代對象中時,加法性能會超過join
- 比較短的字符串,編譯時會被轉換為更短的形式:如‘a’+'b'+'c' 在編譯時被轉換為‘abc’
- 事先知道字符串的數目,可以用字符串格式化str.format()方法或%運算符,此時該format()為最佳方法
集合類型
python內置集合類型有:列表(list),元組(tuple),字典(dictionary),集合(set)
python中組基本的兩種集合類型list和tuple,他們都是對象序列,列表時動態的,大小可變更,元組是不可變的,一旦創建就無法修改,因此也是可哈希(hashtable)的,即可作為字典中的key
列表中的方法操作詳解參考:https://www.cnblogs.com/Devilf/p/8039805.html
列表推導
我們都值都,編寫這樣的代碼時痛苦的
這種方法可能適用與C語言,但在python中的實際運行速度很慢,有以下原因:
- 解釋器在每次循環中都需要判斷序列中的那一部分需要修改
- 需要用一個計數器來跟蹤需要處理的元素
- 由於append()時一個列表方法,所有每次遍歷時都需要額外執行一個查詢函數
列表推導就是為了解決這個問題,它使用編排好的功能對上述語句的一部分做了自動化處理:
這種寫法更加高效簡短,也意味着更少的錯誤,更容易閱讀和理解
創建列表的其他方法(習語)
python習語的另一個典型例子就是使用enumerate(枚舉)。在循環中使用列表時,這個內置函數可以很方便的獲取其索引,列如:
它可以替換為下面這段更短的代碼:
如果需要一個一個合並多個列表(或任意可迭代對象)中的元素,那么可以使用內置的zip()函數。
注意:對zip函數返回的結果再次調用zip,可以將其恢復原狀
另外一種常見的語法元素是序列解包。這種方法適用與任意序列類型(列表,元組,字符串,字節序列等)。只要賦值運算符左邊的變量和右邊的元素數目相等,你都可以用這種方法將元素序列解包到另一邊的變量中:
解包還可以利用帶*的表達式獲取單個變量中的多個元素,只要它的解釋沒有歧義即可。還可以對嵌套序列進行解包。下面是一些更復雜的解包實例:
帶*的表達是可以獲取序列剩余部分
帶*的表達是可以獲取序列的中間部分
嵌套解包
字典
字典可以用和前面列表推導類似的推導來創建一個新的字典。如:
重要的是,使用字典推導具有與列表推導相同的優點,因此字典推導要更加高效,更加簡短,更加簡潔。
字典的keys(),values()和items()3個方法的返回值類型不再是列表,並且與之對應的iterkeys(),itervluae()和iteritems()本來返回的是迭代器,python3中已經沒有這三個方法。python3中keys(),vlaues()和items()返回的是視圖對象(view objects)
- keys():返回dict_keys對象,查看字典的所有鍵
- values():返回dict_values對象,查看字典的所有值
- items():返回dict_items對象,查看字典所有的(key,value)二元組
視圖對象可以動態查看字典的內容,因此每次字典發生變化時,視圖都會相應的變化:
獲取字典長度使用len(len(words)),測試元素是否包含其中使用in子句
在keys和values方法返回的視圖中,鍵和值的順序時完全對應的。但在python2中,如果你想要保證獲取的鍵和值順序完全一致,需要在兩次函數調用之前不能修改字典內容
字典的鍵必須時可哈希(hashable)的(可哈希:一個對象有一個整個生命周期值不變的散列值,並且可以和其他對象進行比較),python所有不變的類型都是可哈希的,可變類型(列表,字典和集合)是不可哈希的
字典是無序的,但是python標准庫的collections模塊提供了名為OrderedDict的有序字典
集合(Set)
集合是一種很棒的數據結構,它與數學中的集合概念類型,有交集,並集等概念
Python的內置集合類型有兩種:
set():可變的,無序的,有限的集合,其元素是唯一的,不可變的對象,集合中的元素必須是可哈希的
frozenset():不可變的,可哈希的,無序的集合,其元素是唯一的,不可變的對象,在一個set()或frozenset()中不能包含另一個普通的可變set(),會拋異常TypeError
下面這種集合初始化的方法是完全正確的:
創建可變集合有三種方法:
- 調用set(),選擇性地接受可迭代對象作為初始化參數,例如set([0,1,2])
- 使用集合推導,例如:{element for element in range(3)}.
- 使用集合字面值,例如{1,2,3}
注意:空的集合對象是沒有字面值的。空的花括號{}表示的是空的字典字面值