前言
學習Demo
Python3的數(shù)據(jù)類型有六種,即其有六個標準的數(shù)據(jù)類型:
- Number(數(shù)字)
- String(字符串)
- List(列表)
- Tuple(元組)
- Sets(集合)
- Dictionary(字典)
一.基本數(shù)據(jù)類型(Number)
一個程序要運行,就要先描述其算法。描述一個算法應先說明算法中要用的數(shù)據(jù),數(shù)據(jù)以變量或常量的形式來描述。每個變量或常量都有數(shù)據(jù)類型。Python3的基本數(shù)據(jù)類型有4種: 整型(int)、浮點型(float)、 布爾型(bool)、complex(復數(shù))。
1.在Python3里,只有一種整數(shù)類型 int,表示為長整型,沒有 python2 中的 Long。
2.像大多數(shù)語言一樣,數(shù)值類型的賦值和計算都是很直觀的。
3.內置的 type() 函數(shù)可以用來查詢變量所指的對象類型。
Python還支持復數(shù),復數(shù)由實數(shù)部分和虛數(shù)部分構成,可以用a + bj,或者complex(a,b)表示, 復數(shù)的實部a和虛部b都是浮點型
a, b, c, d = 20, 5.5, True, 4+3j # Python允許你同時為多個變量賦值
print(type(a), type(b), type(c), type(d)) # 輸出結果: <class 'int'>
<class 'float'> <class 'bool'> <class 'complex'>
此外還可以用 isinstance 來判斷類型:
a, b, c, d = 20, 5.5, True, 4+3j
isinstance(a, int) # 輸出結果: True
sinstance 和 type 的區(qū)別在于:
- type()不會認為子類是一種父類類型。
- isinstance()會認為子類是一種父類類型。
class A:
pass
class B(A):
pass
isinstance(A(), A) # returns True
type(A()) == A # returns True
isinstance(B(), A) # returns True
type(B()) == A # returns False
1.1 bool(布爾值)
- 在 Python2 中是沒有布爾型的,它用數(shù)字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定義成關鍵字了,但它們的值還是 1 和 0,它們可以和數(shù)字相加。
- 此外布爾值可以用and、or和not運算。
- not運算是非運算,它是一個單目運算符,把True變成False,F(xiàn)alse變成True:
>>> True and True
True
>>> True and False
False
>>> False and False
False
>>> 5 > 3 and 3 > 1
True
>>> True or True
True
>>> True or False
True
>>> False or False
False
>>> 5 > 3 or 1 > 3
True
>>> not True
False
>>> not False
True
>>> not 1 > 2
True
1.2 數(shù)值運算
- Python可以同時為多個變量賦值,如a, b = 1, 2。
- 一個變量可以通過賦值指向不同類型的對象。
- 數(shù)值的除法(
/)總是返回一個浮點數(shù),要獲取整數(shù)使用//操作符。 - 在混合計算時,Python會把整型轉換成為浮點數(shù)。
>>> 5 + 4 # 加法
9
>>> 4.3 - 2 # 減法
2.3
>>> 3 * 7 # 乘法
21
>>> 2 / 4 # 除法,得到一個浮點數(shù)
0.5
>>> 2 // 4 # 除法,得到一個整數(shù)
0
>>> 17 % 3 # 取余
2
>>> 2 ** 5 # 乘方
32
1.2 del語句刪除一些對象引用
del語句的語法是:del var1[,var2[,var3[....,varN]]]]
您可以通過使用del語句刪除單個或多個對象。例如:
del var
del var_a, var_b
二.String(字符串)
Python中的字符串用單引號('')或雙引號("")括起來,同時使用反斜杠(\)轉義特殊字符。
2.1 字符串的截取、拼接
- 變量[頭下標:尾下標]
- 索引值以 0 為開始值,-1 為從末尾的開始位置。
- 加號 (
+) 是字符串的連接符, 星號 (*) 表示復制當前字符串,緊跟的數(shù)字為復制的次數(shù)。
#!/usr/bin/python3
str = 'Runoob'
print (str) # 輸出字符串
print (str[0:-1]) # 輸出第一個到倒數(shù)第二個的所有字符
print (str[0]) # 輸出字符串第一個字符
print (str[2:5]) # 輸出從第三個開始到第五個的字符
print (str[2:]) # 輸出從第三個開始的后的所有字符
print (str * 2) # 輸出字符串兩次
print (str + "TEST") # 連接字符串
執(zhí)行以上程序會輸出如下結果:
Runoob
Runoo
R
noo
noob
RunoobRunoob
RunoobTEST
2.2 轉義特殊字符
Python 使用反斜杠(\)轉義特殊字符,如果你不想讓反斜杠發(fā)生轉義,可以在字符串前面添加一個 r,表示原始字符串:
>>> print('Ru\noob')
Ru
oob
>>> print(r'Ru\noob')
Ru\noob
>>>
另外,反斜杠(\)可以作為續(xù)行符,表示下一行是上一行的延續(xù)。也可以使用 """...""" 或者 '''...''' 跨越多行(僅限終端交互模式)。
>>> print('''line1
... line2
... line3''')
line1
line2
line3
注意,Python 沒有單獨的字符類型,一個字符就是長度為1的字符串。
>>> word = 'Python'
>>> print(word[0], word[5])
P n
>>> print(word[-1], word[-6])
n P
2.3 Python中的字符串不能改變
與 C 字符串不同的是,Python 字符串不能被改變。向一個索引位置賦值,比如word[0] = 'm'會導致錯誤。
>>> word = 'Python'
>>> word[0] = 'm' #會導致錯誤
2.4 字符串格式化
| 符 號 | 描述 |
|---|---|
| %c | 格式化字符及其ASCII碼 |
| %s | 格式化字符串 |
| %d | 格式化整數(shù) |
| %u | 格式化無符號整型 |
| %o | 格式化無符號八進制數(shù) |
| %x | 格式化無符號十六進制數(shù) |
| %X | 格式化無符號十六進制數(shù)(大寫) |
| %f | 格式化浮點數(shù)字,可指定小數(shù)點后的精度 |
| %e | 用科學計數(shù)法格式化浮點數(shù) |
| %E | 作用同%e,用科學計數(shù)法格式化浮點數(shù) |
| %g | %f和%e的簡寫 |
| %G | %f 和 %E 的簡寫 |
| %p | 用十六進制數(shù)格式化變量的地址 |
2.5 常用函數(shù)
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import base64
s = 'hello world !'
# 1.把字符串的第一個字符大寫
print('s.capitalize():',s.capitalize())
# 2.返回一個原字符串居中,并使用空格填充至長度 width 的新字符串
print('s.center(20):',s.center(20))
print('s.center(20,\'*\'):',s.center(20,'*'))
# 3.返回 str 在 string 里面出現(xiàn)的次數(shù),如果 beg 或者 end 指定則返回指定范圍內 str 出
# 現(xiàn)的次數(shù)
"""
參數(shù)1:搜索的子字符串;
參數(shù)2:字符串開始搜索的位置。默認為第一個字符,第一個字符索引值為0;
參數(shù)3:字符串中結束搜索的位置。字符中第一個字符的索引為 0。默認為字符串的最后一個位置。
"""
print('s.count(\'l\',0,-1):',s.count('l',0,-1))
# 4.以 encoding 指定的編碼格式解碼 string,如果出錯默認報一個 ValueError 的異常,除非
# errors 指定的是 'ignore' 或者'replace'
"""
python3不太一樣:因為3.x中字符都為unicode編碼,而b64encode函數(shù)的參數(shù)為byte類型,所以必須先轉碼
"""
encodestr = base64.b64encode('abcr34r344r'.encode('utf-8'))
"""
1).encodestr: b'YWJjcjM0cjM0NHI=' 結果和我們預想的有點區(qū)別,我們只想要獲得YWJjcjM0cjM0NHI=
,而字符串被b''包圍了。
2).b 表示 byte的意思,我們只要再將byte轉換回去就好了
"""
print('encodestr:',encodestr)
encodestr1 = str(encodestr,'utf-8', errors='strict')
print('encodestr1:',encodestr1) # encodestr1: YWJjcjM0cjM0NHI=
decodestr = base64.b64decode(encodestr1.encode('utf-8'))
print('decodestr:',decodestr) # b'abcr34r344r'
print(str(decodestr,'utf-8', errors='strict')) # abcr34r344r
# 5.檢查字符串是否以 obj 結束,如果beg或者end指定則檢查指定的范
# 圍(長度)內是否以obj結束,如果是,返回 True,否則返回 False.
print('\'test\'.endswith(\'t\',4):','test'.endswith('t',0,4))
# 6.把字符串中的 tab 符號('\t')轉為空格,tab 符號('\t')默認的空格數(shù)是 8。
# this is string example....wow!!!
print('this is\tstring example....wow!!!'.expandtabs(15))
# 7.檢測 str 是否包含在 string 中,如果 beg 和 end 指定范圍,則檢查是否包含在指定范
# 圍內,如果是返回開始的索引值,否則返回-1
"""
str -- 指定檢索的字符串
beg -- 開始索引,默認為0。
end -- 結束索引,默認為字符串的長度。
注意:檢測到一個就會停止
"""
print(s.find('l',0,10))
# 8.跟find()方法一樣,只不過如果str不在 string中會報一個異常
print('\'good\'.index(\'0\',0,4):','good'.index('o',0,4))
# 9.如果 string 至少有一個字符并且所有字符都是字母或數(shù)字則返回 True,否則返回 False
# (檢測字符串是否由字母和數(shù)字組成)
print("'678'.isalnum():",'678'.isalnum())
print("'6a78'.isalnum():",'6a78'.isalnum())
print("'-he66'.isalnum():",'-he66'.isalnum())
# 10.如果 string 至少有一個字符并且所有字符都是字母則返回 True,否則返回 False(檢測字
# 符串是否只由字母組成)
print("'678'.isalpha():",'678'.isalpha())
print("'6a78'.isalpha():",'6a78'.isalpha())
print("'gegge'.isalpha():",'gegge'.isalpha())
# 11.如果 string 只包含十進制數(shù)字則返回 True 否則返回 False)
# 注意:定義一個十進制字符串,只需要在字符串前添加 'u' 前綴即可。
print("'678'.isdecimal():",'678'.isdecimal())
print("'678a'.isdecimal():",'678a'.isdecimal())
print("'0x124ad'.isdecimal():",'0x124ad'.isdecimal())
# 12.如果 string 只包含數(shù)字則返回 True 否則返回 False.
print("'678'.isdigit():",'678'.isdigit())
print("'678t'.isdigit():",'678t'.isdigit())
# 13.如果 string 中只包含數(shù)字字符,則返回 True,否則返回 False
print("'678'.isnumeric():",'678'.isnumeric())
print("'678t'.isnumeric():",'678t'.isnumeric())
# 14.如果 string 中包含至少一個區(qū)分大小寫的字符,并且所有這些(區(qū)分大小寫的)字符都是
# 小寫,則返回 True,否則返回 False(檢測字符串是否由小寫字母組成)
print("'test'.islower():",'test'.islower())
print("'Test'.islower():",'Test'.islower())
# 15.如果 string 中包含至少一個區(qū)分大小寫的字符,并且所有這些(區(qū)分大小寫的)字符都是大
# 寫,則返回 True,否則返回 False
print("'test'.isupper():",'test'.isupper())
print("'TEST'.isupper():",'TEST'.isupper())
# 16.如果 string 中只包含空格,則返回 True,否則返回 False
print("' '.isspace():",' '.isspace())
print("'This is string example....wow!!!'.isspace():",
'This is string example....wow!!!'.isspace())
# 17.如果 string 是標題化的(見 title())則返回 True,否則返回 False
print("'This Is A Test'.istitle():",'This Is A Test'.istitle())
print("'This is a test'.istitle():",'This is a test'.istitle())
# 18.以 string 作為分隔符,將 seq 中所有的元素(的字符串表示)合并為一個新的字符串(將序
# 列中的元素以指定的字符連接生成一個新的字符串)
seq = ("r", "u", "n", "o", "o", "b") # 字符串序列
print ("'-'.join(seq):",'-'.join(seq))
print ("''.join(seq):",''.join(seq))
# 19.len() 方法返回對象(字符、列表、元組等)長度或項目個數(shù)
print("len('hello'):", len('hello'))
# 20.返回一個原字符串左對齊,并使用空格填充至長度 width 的新字符串
print("'hello'.ljust(20,'*'):", 'hello'.ljust(20,'*'))
# 21.轉換 string 中所有大寫字符為小寫
print("'HELLO'.lower():", 'HELLO'.lower())
# 22.轉換 string 中的小寫字母為大寫
print("'hello'.upper():", 'hello'.upper())
# 23.截掉 string 左邊的字符
print("' hello'.lstrip(' '):", ' hello'.lstrip(' '))
print("'88888hello'.lstrip(' '):", ' hello'.lstrip('8'))
# 24.maketrans() 方法用于創(chuàng)建字符映射的轉換表,對于接受兩個參數(shù)的最簡單的調用方式,
# 第一個參數(shù)是字符串,表示需要轉換的字符,第二個參數(shù)也是字符串表示轉換的目標
"""
maketrans() 方法用于創(chuàng)建字符映射的轉換表,對于接受兩個參數(shù)的最簡單的調用方式,
第一個參數(shù)是字符串,表示需要轉換的字符;
第二個參數(shù)也是字符串表示轉換的目標。
兩個字符串的長度必須相同,為一一對應的關系。
注:Python3.4已經(jīng)沒有string.maketrans()了,取而代之的是內建
函數(shù): bytearray.maketrans()、bytes.maketrans()、str.maketrans()
"""
# 以下實例展示了使用maketrans() 方法將所有元音字母轉換為指定的數(shù)字
intab = "aeiou"
outtab = "12345"
trantab = str.maketrans(intab, outtab)
str = "this is string example....wow!!!"
print (str.translate(trantab))
# 25.返回字符串 str 中最大的字母
print("max('abjzkqp'):", max('abjzkqp'))
# 26.返回字符串 str 中最小的字母
print("min('abjzkqp'):", min('abjzkqp'))
# 27.返回長度為 width 的字符串,原字符串 string 右對齊,前面填充0
print("'world'.zfill(20):", 'world'.zfill(20))
# 28.翻轉 string 中的大小寫
print("'WorLd'.swapcase():", 'WorLd'.swapcase())
# 29.返回"標題化"的 string,就是說所有單詞都是以大寫開始,其余字母均為小寫(見 istitle())
print("'this is a test'.title():", 'this is a test'.title())
# 30.把 string 中的 str1 替換成 str2,如果 num 指定,則替換不超過 num 次.
print("'this is a test'.replace('s','q',3):", 'this is a test'.replace('s','q',3))
# 31.類似于find()函數(shù),不過是從右邊開始查找(返回字符串最后一次出現(xiàn)的位置,如果沒有匹配項則
# 返回-1)
"""
str -- 查找的字符串
beg -- 開始查找的位置,默認為0
end -- 結束查找位置,默認為字符串的長度。
"""
print("'hello'.rfind('l',0,5):", 'hello'.rfind('l',0,5))
# 32.類似于index(),不過是從右邊開始(返回子字符串str在字符串中最后出現(xiàn)的位置,如果沒有匹配的
# 字符串會報異常)
print("'hello'.rindex('l',0,5):", 'hello'.rindex('l',0,5))
# 33.返回一個原字符串右對齊,并使用空格填充至長度 width 的新字符串
print("'test'.rjust(20,'*'):", 'test'.rjust(20,'*'))
# 34.刪除 string 字符串末尾的指定字符(默認為空格)
print("'world*****'.rstrip('*'):", 'world*****'.rstrip('*'))
# 35.在string上執(zhí)行l(wèi)strip()和rstrip()(用于移除字符串頭尾指定的字符(默認為空格))
print("'***test***'.strip('*'):", '***test***'.strip('*'))
# 36.根據(jù) str 給出的表(包含 256 個字符)轉換 string 的字符,要過濾掉的字符放到 del 參數(shù)中
"""
able -- 翻譯表,翻譯表是通過 maketrans() 方法轉換而來。
deletechars -- 字符串中要過濾的字符列表。
"""
bytes_tabtrans = bytes.maketrans(b'abcdefghijklmnopqrstuvwxyz',
b'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
print(b'runoob'.translate(bytes_tabtrans, b'o')) # 轉換為大寫,并刪除字母o
# 37.檢查字符串是否是以obj開頭,是則返回True,否則返回False。如果beg和end 指定值,則在指定范
# 圍內檢查
print("'test'.startswith('t',0,4):", 'test'.startswith('t',0,4))
# 38.以 str 為分隔符切片 string,如果 num有指定值,則僅分隔 num 個子字符串
"""
str -- 分隔符,默認為所有的空字符,包括空格、換行(\n)、制表符(\t)等。
num -- 分割次數(shù)。
"""
str = "this is string example....wow!!!"
print(str.split( )) # ['this', 'is', 'string', 'example....wow!!!']
print(str.split('i',1)) # ['th', 's is string example....wow!!!']
print(str.split('w')) # ['this is string example....', 'o', '!!!']
# 39.按照行('\r', '\r\n', \n')分隔,返回一個包含各行作為元素的列表,
# 如果參數(shù) keepends 為 False,不包含換行符,如果為 True,則保留換行符
# ['ab c', '', 'de fg', 'kl']
print('ab c\n\nde fg\rkl\r\n'.splitlines())
# ['ab c\n', '\n', 'de fg\r', 'kl\r\n']
print('ab c\n\nde fg\rkl\r\n'.splitlines(True))
# 40.有點像 find()和 split()的結合體,從 str 出現(xiàn)的第一個位置起,把字
# 符串string分成一個3元素的元組 (string_pre_str,str,string_post_str)
# ,如果 string 中不包含str 則 string_pre_str == string.
# 根據(jù)指定的分隔符將字符串進行分割
"""
如果字符串包含指定的分隔符,則返回一個3元的元組,第一個為分隔符左邊的子串,
第二個為分隔符本身,第三個為分隔符右邊的子串
"""
str6 = "https://www.baidu.com/"
print(str6.partition("://"))
# 41.類似于 partition()函數(shù),不過是從右邊開始查找
print(str6.rpartition("://"))
三.空值(None)。
空值是Python里一個特殊的值,用None表示。None不能理解為0,因為0是有意義的,而None是一個特殊的空值。
四. List(列表:有序可變)
- List(列表) 是 Python 中使用最頻繁的數(shù)據(jù)類型。與Objective-C中的NSMutableArray類似。
- 列表可以完成大多數(shù)集合類的數(shù)據(jù)結構實現(xiàn)。列表中元素的類型可以不相同,它支持數(shù)字,字符串甚至可以包含列表(所謂嵌套)。
- 列表是寫在方括號(
[])之間、用逗號分隔開的元素列表。 - 和字符串一樣,列表同樣可以被索引和截取,列表被截取后返回一個包含所需元素的新列表。
4.1 創(chuàng)建列表:
# 方法一:
ame_list = ['alex', 'seven', 'eric']
# 方法二:
name_list = list(['alex', 'seven', 'eric'])
4.2 常用函數(shù):
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import copy
a = 89
b = '6'
ame_list = [68, 68, 58, 108945, 1, 75, 69] # 列表1
temp_list = [55, 75, 452, 7856, 4553, 45354, 54] # 列表2
temp_list1 = ['b','y','q','a','k','z','p','b' ] # 列表3
tup1 = ('Google', 'Runoob', 1997, 2000) # 元組
# 1.列表元素個數(shù)
print(len(ame_list))
# 2.返回列表元素最大值
print(max(ame_list))
# 3.返回列表元素最小值
print(min(ame_list))
# 4.將元組轉換為列表
print(list(tup1))
# 5.在列表末尾添加新的對象
ame_list.append(a)
print(ame_list)
# 6.統(tǒng)計某個元素在列表中出現(xiàn)的次數(shù)
print(ame_list.count(68))
# 7.在列表末尾一次性追加另一個序列中的多個值(用新列表擴展原來的列表)
(ame_list.extend(temp_list))
print(ame_list)
# 8.從列表中找出某個值第一個匹配項的索引位置
print(ame_list.index(1,0,6)) # 參數(shù):value,起始位置,結束位置
print(ame_list.index(75)) # 無起始值則遍歷所有value
# 9.將對象插入列表
'''
共有如下5種場景:
場景1:index=0時,從頭部插入obj
場景2:index > 0 且 index < len(list)時,在index的位置插入obj
場景3:當index < 0 且 abs(index) < len(list)時,從中間插入obj,
如: -1 表示從倒數(shù)第1位插入obj; -2 表示從倒數(shù)第2位插入obj
場景4:當index < 0 且 abs(index) >= len(list)時,從頭部插入obj
場景5:當index >= len(list)時,從尾部插入obj
'''
ame_list.insert(2,198) # 參數(shù):插入位置,插入值
print(ame_list)
# 10.移除列表中的一個元素(默認最后一個元素),并且返回該元素的值
print(ame_list.pop(-1)) # -1代表最后一個元素
print(ame_list)
# 11.移除列表中某個值的第一個匹配項
ame_list.remove(68)
print(ame_list)
# 12.反向列表中元素
ame_list.reverse()
print(ame_list)
# 13.對原列表進行排序 list.sort([func])
ame_list.sort() # func 可選參數(shù), 如果指定了該參數(shù)會使用該參數(shù)的方法進行排序。
print(ame_list)
# 14.復制列表( copy() 函數(shù)用于復制列表,類似于 a[:])。
new_list1 = copy.copy(temp_list1) # 要導入copy類import copy
new_list2 = copy.deepcopy(temp_list1)
print(new_list1)
print(new_list2)
# 15.清空列表 (clear() 函數(shù)用于清空列表,類似于 del a[:]。)
new_list2.clear() # clear()函數(shù)3.x以上版本才有,2.x無
print(new_list2)
五. Tuple(元組:有序不可變)
不可變列表類似Objective-C中的NSArray,初始化如下:
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 方法一:
ages = (11, 22, 33, 44, 55)
# 方法二:
ages = tuple((11, 22, 33, 44, 55))
5.1 訪問元組
#!/usr/bin/python3
tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print ("tup1[0]: ", tup1[0]) # tup1[0]: Google
print ("tup2[1:5]: ", tup2[1:5]) # tup2[1:5]: (2, 3, 4, 5)
5.2 刪除元組
元組中的元素值是不允許刪除的,但我們可以使用del語句來刪除整個元組
#!/usr/bin/python3
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup;
print ("刪除后的元組 tup : ")
print (tup) # 以上實例元組被刪除后,輸出變量會有異常信息,輸出如下所示:
"""
('Google', 'Runoob', 1997, 2000)
Traceback (most recent call last):
刪除后的元組 tup :
File "/Users/ysf/Desktop/Python/package1/LYDictionary.py", line 11, in <module>
print (tup) # 以上實例元組被刪除后,輸出變量會有異常信息,輸出如下所示:
NameError: name 'tup' is not defined
"""
5.3 注意點
- 注意點一:
# 但是,要定義一個只有1個元素的tuple,如果你這么定義:
>>> t = (1)
>>> t
# 輸出結果是:1
"""
定義的不是tuple,是1這個數(shù)!這是因為括號()既可以表示tuple,又可以表示數(shù)學公式中的小括號,這就產
生了歧義,因此,Python規(guī)定,這種情況下,按小括號進行計算,計算結果自然是1。所以,只有1個元素的
tuple定義時必須加一個逗號(,)來消除歧義:
"""
>>> t = (1,)
>>> t
# 輸出結果是:(1,)
- 注意點二:“可變的”tuple:
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
# 輸出結果是:('a', 'b', ['X', 'Y'])
"""
這個tuple定義的時候有3個元素,分別是'a','b'和一個list。不是說tuple一旦定義后就不可變了嗎?怎么
后來又變了?表面上看,tuple的元素確實變了,但其實變的不是tuple的元素,而是list的元素。tuple一開
始指向的list并沒有改成別的list,所以,tuple所謂的“不變”是說,tuple的每個元素,指向永遠不變。即
指向'a',就不能改成指向'b',指向一個list,就不能改成指向其他對象,但指向的這個list本身是可變的!
所以說要創(chuàng)建一個內容也不變的tuple,那就必須保證tuple的每一個元素本身也不能變。
"""

六. Dictionary(字典可變)
字典是另一種可變容器模型,且可存儲任意類型對象,在其他語言中也稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號({})中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
6.1 dict的實現(xiàn)原理
為什么dict查找速度這么快?因為dict的實現(xiàn)原理和查字典是一樣的。假設字典包含了1萬個漢字,我們要查某一個字,一個辦法是把字典從第一頁往后翻,直到找到我們想要的字為止,這種方法就是在list中查找元素的方法,list越大,查找越慢。
第二種方法是先在字典的索引表里(比如部首表)查這個字對應的頁碼,然后直接翻到該頁,找到這個字。無論找哪個字,這種查找速度都非???,不會隨著字典大小的增加而變慢。
dict就是第二種實現(xiàn)方式,給定一個名字,比如'Michael',dict在內部就可以直接計算出Michael對應的存放成績的“頁碼”,也就是95這個數(shù)字存放的內存地址,直接取出來,所以速度非??臁_@種key-value存儲方式,在放進去的時候,必須根據(jù)key算出value的存放位置,這樣,取的時候才能根據(jù)key直接拿到value。
6.2 特性及常用函數(shù)
- 鍵必須是唯一的,但值則不必。
- 值可以取任何數(shù)據(jù)類型,但鍵必須是不可變的,如字符串,數(shù)字或元組。(鍵必須不可變,所以可以用數(shù)字,字符串或元組充當,而用列表就不行)
- 一個key只能對應一個value,所以多次對一個key放入value,后面的值會把前面的值覆蓋
- 如果key不存在,dict就會報錯
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 1.字典初始化
dict1 = {'name': 'sam', 98.6: 37, 'sex': '男', 'height': 188, 'car': '路虎'}
dict2 = {'name': 'sam', 98.6: 37, 'sex': '男', 'height': 188}
print("dict1: ", dict1)
# 2.訪問字典里的值
print("dict1['name']: ", dict1['name'])
# 3.避免key不存在的錯誤,有兩種辦法,一是通過in判斷key是否存在;二是通過dict提供的get()方法,如
#果key不存在,可以返回None,或者自己指定的value:
print("age in dict1: ", 'age' in dict1) # 方法一
print("age in dict1: ", dict1.get('age')) # 方法二 默認值為None
print("age in dict1: ", dict1.get('age', -1)) # 方法二 自定義value
# 4.和get()類似, 但如果鍵不存在于字典中,將會添加鍵并將值設為default
print("dict1.setdefault: ", dict1.setdefault('Taobao', '淘寶'))
# 5.刪除一個key
print("dict1.pop('name'): ", dict1.pop('name'))
print("dict1: ", dict1)
# 6.計算字典元素個數(shù),即鍵的總數(shù)。
print("len(dict1): ", len(dict1))
# 7.輸出字典,以可打印的字符串表示。
print("str(dict1): ", str(dict1))
# 8.返回輸入的變量類型,如果變量是字典就返回字典類型。
print("type(dict1): ", type(dict1)) # <class 'dict'>
# 9.刪除字典內所有元素
dict2.clear()
print("dict2: ", dict2)
# 10.返回一個字典的淺復制
print("dict1.copy(): ", dict1.copy())
# 11.以列表返回可遍歷的(鍵, 值)元組數(shù)組
print("dict1.items(): ", dict1.items())
# 12.以列表返回一個字典所有的鍵
print("dict1.keys(): ", dict1.keys())
# 13.以列表返回字典中的所有值
print("dict1.values(): ", dict1.values())
# 14.把字典dict1的鍵/值對更新到dict2里
dict2.update(dict1)
print("dict2.update(dict1)后dict2的值: ", dict2)
# 15.刪除字典給定鍵 key 所對應的值,返回值為被刪除的值。key值必須給出。 否則,返回default值。
dict1.pop('car')
print("dict1: ", dict1)
# 16.隨機返回并刪除字典中的一對鍵和值(一般刪除末尾對)。
dict2.popitem()
print("dict2: ", dict2)
# 17.創(chuàng)建一個新字典,以序列seq中元素做字典的鍵,val為字典所有鍵對應的初始值
seq = ('name', 'age', 'sex')
dict3 = dict.fromkeys(seq)
print("新的字典為 : %s", str(dict3)) # 全部key的value都默認賦值為:None
dict4 = dict.fromkeys(seq, 10) # 全部key的value都賦值為:10
print("新的字典全部key的value都賦值為:10 : %s", str(dict4))
# 18.鍵用列表會報錯
dict5 = {['Name']: 'Runoob','Age': 7}
"""
Traceback (most recent call last):
File "/Users/ysf/Desktop/Python/package1/LYDictionary.py", line 30, in <module>
dict = {['Name']: 'Runoob', 'Age': 7}
TypeError: unhashable type: 'list'
"""
# 19.如果用字典里沒有的鍵訪問數(shù)據(jù),會輸出錯誤
print("dict1['job']: ", dict1['job'])
"""
Traceback (most recent call last):
File "/Users/ysf/Desktop/Python/package1/LYDictionary.py", line 63, in <module>
print("dict1['job']: ", dict1['job'])
KeyError: 'job'
"""
6.3 dict和list的優(yōu)缺點
和list比較,dict有以下幾個特點:
- 查找和插入的速度極快,不會隨著key的增加而變慢;
- 需要占用大量的內存,內存浪費多。
list優(yōu)缺點:
- 查找和插入的時間隨著元素的增加而增加;
- 占用空間小,浪費內存很少。
總結:所以,dict是用空間來換取時間的一種方法。dict可以用在需要高速查找的很多地方,在Python代碼中幾乎無處不在,正確使用dict非常重要,需要牢記的第一條就是dict的key必須是不可變對象。
這是因為dict根據(jù)key來計算value的存儲位置,如果每次計算相同的key得出的結果不同,那dict內部就完全混亂了。這個通過key計算位置的算法稱為哈希算法(Hash)。要保證hash的正確性,作為key的對象就不能變。在Python中,字符串、整數(shù)等都是不可變的,因此,可以放心地作為key。而list是可變的,就不能作為key:
七. Set(無序不重復元素集合)
set和dict類似,也是一組key的集合,但不存儲value。由于key不能重復,所以,在set中,沒有重復的key??偨Y:set和dict的唯一區(qū)別僅在于沒有存儲對應的value。
7.1 Set特性
- 集合(set)是一個無序不重復元素的序列。
- 基本功能是進行成員關系測試和刪除重復元素。
- 可以使用大括號
{ }或者set()函數(shù)創(chuàng)建集合,注意:創(chuàng)建一個空集合必須用set()而不是{ },因為{ }是用來創(chuàng)建一個空字典。
7.2 創(chuàng)建Set
# 方法一:
parame = {value01,value02,...}
# 方法二:
set(value)
7.3 基本用法
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# 1.創(chuàng)建一個set,需要提供一個list作為輸入集合,重復元素在set中自動被過濾
s = set([1, 1, 2, 2, 3, 3]) # {1, 2, 3}
# 2.通過add(key)方法可以添加元素到set中,可以重復添加,但只有第一次有效果
s.add(4) # {1, 2, 3, 4}
s.add(4) # {1, 2, 3, 4}
# 3.通過remove(key)方法可以刪除元素
s.remove(4) # {1, 2, 3},不能移除不存在的key
# 4.set可以看成數(shù)學意義上的無序和無重復元素的集合,因此,兩個set可以做數(shù)學意義上的交集、并集
# 等操作:
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
print("s1 & s2: ", s1 & s2) # {2, 3}
print("s1 | s2: ", s1 | s2) # {1, 2, 3, 4}