老師博客copy

 

Py西遊攻關之基礎數據類型

 

數據類型

計算機顧名思義就是能夠作數學計算的機器,所以,計算機程序理所固然地能夠處理各類數值。可是,計算機能處理的遠不止數值,還能夠處理文本、圖形、音頻、視頻、網頁等各類各樣的數據,不一樣的數據,須要定義不一樣的數據類型。在Python中,可以直接處理的數據類型有如下幾種html

一 Number(數字)

1.1 數字類型的建立

?
1
2
3
4
5
6
a = 10
b = a
b = 666
 
print (a) #10
print (b) #666

 

注意這裏與C的不一樣:python

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
void main(void)
{
 
     int a = 1 ;
     int b = a;
     printf ( "a:adr:%p,val:%d,b:adr:%p,val:%d\n" ,&a,a,&b,b);
     a = 3 ;
     printf ( "a:adr:%p,val:%d,b:adr:%p,val:%d\n" ,&a,a,&b,b);
 
}
 
/ / 打印結果:
topeet@ubuntu:~$ gcc test.c
topeet@ubuntu:~$ . / a.out
a:adr: 0x7fff343a069c ,val: 1
b:adr: 0x7fff343a0698 ,val: 1
a:adr: 0x7fff343a069c ,val: 3
b:adr: 0x7fff343a0698 ,val: 1

1.2 Number 類型轉換

?
1
2
3
4
5
6
var1 = 3.14
var2 = 5
var3 = int (var1)
var4 = float (var2)
 
print (var3,var4)
abs(x)    返回數字的絕對值,如abs(-10) 返回 10
# ceil(x)    返回數字的上入整數,如math.ceil(4.1) 返回 5
# cmp(x, y)    若是 x < y 返回 -1, 若是 x == y 返回 0, 若是 x > y 返回 1
# exp(x)    返回e的x次冪(ex),如math.exp(1) 返回2.718281828459045
# fabs(x)    返回數字的絕對值,如math.fabs(-10) 返回10.0
# floor(x)    返回數字的下舍整數,如math.floor(4.9)返回 4
# log(x)    如math.log(math.e)返回1.0,math.log(100,10)返回2.0
# log10(x)    返回以10爲基數的x的對數,如math.log10(100)返回 2.0
# max(x1, x2,...)    返回給定參數的最大值,參數能夠爲序列。
# min(x1, x2,...)    返回給定參數的最小值,參數能夠爲序列。
# modf(x)    返回x的整數部分與小數部分,兩部分的數值符號與x相同,整數部分以浮點型表示。
# pow(x, y)    x**y 運算後的值。
# round(x [,n])    返回浮點數x的四捨五入值,如給出n值,則表明舍入到小數點後的位數。
# sqrt(x)    返回數字x的平方根,數字能夠爲負數,返回類型爲實數,如math.sqrt(4)返回 2+0j
PY內置數學函數

二 字符串類型(string)

字符串是以單引號'或雙引號"括起來的任意文本,好比'abc'"123"等等。git

請注意,''""自己只是一種表示方式,不是字符串的一部分,所以,字符串'abc'只有abc這3個字符。若是'自己也是一個字符,那就能夠用""括起來,好比"I'm OK"包含的字符是I'm,空格,OK這6個字符。編程

2.1 建立字符串:ubuntu

?
1
2
var1 = 'Hello World!'
var2 = "Python RAlvin"

對應操做:api

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1   * 重複輸出字符串
print ( 'hello' * 2 )
 
# 2 [] ,[:] 經過索引獲取字符串中字符,這裏和列表的切片操做是相同的,具體內容見列表
print ( 'helloworld' [ 2 :])
 
# 3 in  成員運算符 - 若是字符串中包含給定的字符返回 True
print ( 'el' in 'hello' )
 
# 4 %   格式字符串
print ( 'alex is a good teacher' )
print ( '%s is a good teacher' % 'alex' )
 
 
# 5 +   字符串拼接
a = '123'
b = 'abc'
c = '789'
d1 = a + b + c
print (d1)
# +效率低,該用join
d2 = ''.join([a,b,c])
print (d2)

python的內置方法服務器

# string.capitalize()                                  把字符串的第一個字符大寫
# string.center(width)                                 返回一個原字符串居中,並使用空格填充至長度 width 的新字符串
# string.count(str, beg=0, end=len(string))            返回 str 在 string 裏面出現的次數,若是 beg 或者 end 指定則返回指定範圍內 str 出現的次數
# string.decode(encoding='UTF-8', errors='strict')     以 encoding 指定的編碼格式解碼 string,若是出錯默認報一個 ValueError 的 異 常 , 除 非 errors 指 定 的 是 'ignore' 或 者'replace'
# string.encode(encoding='UTF-8', errors='strict')     以 encoding 指定的編碼格式編碼 string,若是出錯默認報一個ValueError 的異常,除非 errors 指定的是'ignore'或者'replace'
# string.endswith(obj, beg=0, end=len(string))         檢查字符串是否以 obj 結束,若是beg 或者 end 指定則檢查指定的範圍內是否以 obj 結束,若是是,返回 True,不然返回 False.
# string.expandtabs(tabsize=8)                         把字符串 string 中的 tab 符號轉爲空格,tab 符號默認的空格數是 8。
# string.find(str, beg=0, end=len(string))             檢測 str 是否包含在 string 中,若是 beg 和 end 指定範圍,則檢查是否包含在指定範圍內,若是是返回開始的索引值,不然返回-1
# string.index(str, beg=0, end=len(string))            跟find()方法同樣,只不過若是str不在 string中會報一個異常.
# string.isalnum()                                     若是 string 至少有一個字符而且全部字符都是字母或數字則返回 True,不然返回 False
# string.isalpha()                                     若是 string 至少有一個字符而且全部字符都是字母則返回 True,不然返回 False
# string.isdecimal()                                   若是 string 只包含十進制數字則返回 True 不然返回 False.
# string.isdigit()                                     若是 string 只包含數字則返回 True 不然返回 False.
# string.islower()                                     若是 string 中包含至少一個區分大小寫的字符,而且全部這些(區分大小寫的)字符都是小寫,則返回 True,不然返回 False
# string.isnumeric()                                   若是 string 中只包含數字字符,則返回 True,不然返回 False
# string.isspace()                                     若是 string 中只包含空格,則返回 True,不然返回 False.
# string.istitle()                                     若是 string 是標題化的(見 title())則返回 True,不然返回 False
# string.isupper()                                     若是 string 中包含至少一個區分大小寫的字符,而且全部這些(區分大小寫的)字符都是大寫,則返回 True,不然返回 False
# string.join(seq)                                     以 string 做爲分隔符,將 seq 中全部的元素(的字符串表示)合併爲一個新的字符串
# string.ljust(width)                                  返回一個原字符串左對齊,並使用空格填充至長度 width 的新字符串
# string.lower()                                       轉換 string 中全部大寫字符爲小寫.
# string.lstrip()                                      截掉 string 左邊的空格
# string.maketrans(intab, outtab])                     maketrans() 方法用於建立字符映射的轉換表,對於接受兩個參數的最簡單的調用方式,第一個參數是字符串,表示須要轉換的字符,第二個參數也是字符串表示轉換的目標。
# max(str)                                             返回字符串 str 中最大的字母。
# min(str)                                             返回字符串 str 中最小的字母。
# string.partition(str)                                有點像 find()和 split()的結合體,從 str 出現的第一個位置起,把 字 符 串 string 分 成 一 個 3 元 素 的 元 組 (string_pre_str,str,string_post_str),若是 string 中不包含str 則 string_pre_str == string.
# string.replace(str1, str2,  num=string.count(str1))  把 string 中的 str1 替換成 str2,若是 num 指定,則替換不超過 num 次.
# string.rfind(str, beg=0,end=len(string) )            相似於 find()函數,不過是從右邊開始查找.
# string.rindex( str, beg=0,end=len(string))           相似於 index(),不過是從右邊開始.
# string.rjust(width)                                  返回一個原字符串右對齊,並使用空格填充至長度 width 的新字符串
# string.rpartition(str)                               相似於 partition()函數,不過是從右邊開始查找.
# string.rstrip()                                      刪除 string 字符串末尾的空格.
# string.split(str="", num=string.count(str))          以 str 爲分隔符切片 string,若是 num有指定值,則僅分隔 num 個子字符串
# string.splitlines(num=string.count('\n'))            按照行分隔,返回一個包含各行做爲元素的列表,若是 num 指定則僅切片 num 個行.
# string.startswith(obj, beg=0,end=len(string))        檢查字符串是不是以 obj 開頭,是則返回 True,不然返回 False。若是beg 和 end 指定值,則在指定範圍內檢查.
# string.strip([obj])                                  在 string 上執行 lstrip()和 rstrip()
# string.swapcase()                                    翻轉 string 中的大小寫
# string.title()                                       返回"標題化"的 string,就是說全部單詞都是以大寫開始,其他字母均爲小寫(見 istitle())
# string.translate(str, del="")                        根據 str 給出的表(包含 256 個字符)轉換 string 的字符,要過濾掉的字符放到 del 參數中
# string.upper()                                       轉換 string 中的小寫字母爲大寫
View Code

三 字節類型(bytes)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# a=bytes('hello','utf8')
# a=bytes('中國','utf8')
 
 
a = bytes( '中國' , 'utf8' )
b = bytes( 'hello' , 'gbk' )
#
print (a)        #b'\xe4\xb8\xad\xe5\x9b\xbd'
print ( ord ( 'h' )) #其十進制 unicode 值爲: 104
print ( ord ( '中' )) #其十進制 unicode 值爲:20013
 
#  h   e  l   l   o
# 104 101 108 108 111   編碼後結果:與ASCII表對應
 
 
#     中                國
#   \xd6\xd0         \xb9\xfa       gbk編碼後的字節結果
#\xe4 \xb8 \xad   \xe5 \x9b \xbd    utf8編碼後的字節結果
# 228 184 173      229 155  189        a[:]切片取
 
 
c = a.decode( 'utf8' )
d = b.decode( 'gbk' )
#b=a.decode('gbk') :很明顯報錯
 
print (c) #中國
print (d) #hello 

注意:對於 ASCII 字符串,由於不管哪一種編碼對應的結果都是同樣的,因此能夠直接使用 b'xxxx' 賦值建立 bytes 實例,但對於非 ASCII 編碼的字符則不能經過這種方式建立 bytes 實例,須要指明編碼方式。數據結構

?
1
2
3
4
5
6
b1 = b '123'
print ( type (b1))
# b2=b'中國' #報錯
# 因此得這樣:
b2 = bytes( '中國' , 'utf8' )
print (b2) #b'\xe4\xb8\xad\xe5\x9b\xbd'

四 布爾值

一個布爾值只有TrueFalse兩種值,要麼是True,要麼是False,在Python中,能夠直接用TrueFalse表示布爾值(請注意大小寫)app

?
1
2
3
4
print ( True )
print ( 4 > 2 )
print ( bool ([ 3 , 4 ]))
print ( True + 1 )

與或非操做:less

?
1
2
3
4
bool ( 1 and 0 )
bool ( 1 and 1 )
bool ( 1 or 0 )
bool ( not 0 )

布爾值常常用在條件判斷中:

?
1
2
3
4
5
age = 18
if age> 18 : #bool(age>18)
     print ( 'old' )
else :
     print ( 'young' )

  

五 List(列表)

      OK,如今咱們知道了字符串和整型兩個數據類型了,那需求來了,我想把某個班全部的名字存起來,怎麼辦?

有同窗說,不是學變量存儲了嗎,我就用變量存儲唄,呵呵,不嫌累嗎,同窗,如班裏有一百我的,你就得建立一百個變量啊,消耗大,效率低。

又有同窗說,我用個大字符串不能夠嗎,沒問題,你的確存起來了,可是,你對這個數據的操做(增刪改查)將變得很是艱難,不是嗎,我想知道張三的位置,你怎麼辦?

 

在這種需求下,編程語言有了一個重要的數據類型----列表(list)

 

什麼是列表:

列表(list)是Python以及其餘語言中最經常使用到的數據結構之一。Python使用使用中括號 [ ] 來解析列表。列表是可變的(mutable)——能夠改變列表的內容。

 

對應操做:

1 查([])

?
1
2
3
4
5
6
7
8
9
10
names_class2 = [ '張三' , '李四' , '王五' , '趙六' ]
 
# print(names_class2[2])
# print(names_class2[0:3])
# print(names_class2[0:7])
# print(names_class2[-1])
# print(names_class2[2:3])
# print(names_class2[0:3:1])
# print(names_class2[3:0:-1])
# print(names_class2[:]) 

2 增(append,insert)

insert 方法用於將對象插入到列表中,而append方法則用於在列表末尾追加新的對象

?
1
2
3
names_class2.append( 'alex' )
names_class2.insert( 2 , 'alvin' )
print (names_class2)

3 改(從新賦值)

?
1
2
3
4
5
names_class2 = [ '張三' , '李四' , '王五' , '趙六' ]
 
names_class2[ 3 ] = '趙七'
names_class2[ 0 : 2 ] = [ 'wusir' , 'alvin' ]
print (names_class2)

4 刪(remove,del,pop)

?
1
2
3
4
names_class2.remove( 'alex' )
del names_class2[ 0 ]
del names_class2
names_class2.pop() #注意,pop是有一個返回值的 

5 其餘操做

5.1  count

       count 方法統計某個元素在列表中出現的次數:

?
1
2
3
4
5
6
7
>>> [ 'to' , 'be' , 'or' , 'not' , 'to' , 'be' ].count( 'to'
2 
>>> x = [[ 1 , 2 ], 1 , 1 , [ 2 , 1 , [ 1 , 2 ]]] 
>>> x.count( 1
2 
>>> x.count([ 1 , 2 ]) 
1

5.2 extend

         extend 方法能夠在列表的末尾一次性追加另外一個序列中的多個值。

?
1
2
3
4
5
>>> a = [ 1 , 2 , 3
>>> b = [ 4 , 5 , 6
>>> a.extend(b) 
>>> a 
[ 1 , 2 , 3 , 4 , 5 , 6

  extend 方法修改了被擴展的列表,而原始的鏈接操做(+)則否則,它會返回一個全新的列表。

?
1
2
3
4
5
6
7
8
9
10
>>> a = [ 1 , 2 , 3
>>> b = [ 4 , 5 , 6
>>> a.extend(b) 
>>> a 
[ 1 , 2 , 3 , 4 , 5 , 6
>>> 
>>> a +
[ 1 , 2 , 3 , 4 , 5 , 6 , 4 , 5 , 6
>>> a 
[ 1 , 2 , 3 , 4 , 5 , 6

5.3  index

       index 方法用於從列表中找出某個值第一個匹配項的索引位置: 

?
1
names_class2.index( '李四' )

5.4  reverse

       reverse 方法將列表中的元素反向存放。

?
1
2
names_class2.reverse()
print (names_class2)

5.5  sort

       sort 方法用於在原位置對列表進行排序。

?
1
2
x = [ 4 , 6 , 2 , 1 , 7 , 9 ]
x.sort() #x.sort(reverse=True)

5.6  深淺拷貝

如今,你們先不要理會什麼是深淺拷貝,聽我說,對於一個列表,我想複製一份怎麼辦呢?

確定會有同窗說,從新賦值唄:

?
1
2
names_class1 = [ '張三' , '李四' , '王五' , '趙六' ]
names_class1_copy = [ '張三' , '李四' , '王五' , '趙六' ]

這是兩塊獨立的內存空間

這也沒問題,仍是那句話,若是列表內容作夠大,你真的能夠要每個元素都從新寫一遍嗎?固然不啦,因此列表裏爲咱們內置了copy方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
names_class1 = [ '張三' , '李四' , '王五' , '趙六' ,[ 1 , 2 , 3 ]]
names_class1_copy = names_class1.copy()
 
names_class1[ 0 ] = 'zhangsan'
print (names_class1)
print (names_class1_copy)
 
############
names_class1[ 4 ][ 2 ] = 5
print (names_class1)
print (names_class1_copy)
 
#問題來了,爲何names_class1_copy,從這一點咱們能夠判定,這兩個變量並非徹底獨立的,那他們的關係是什麼呢?爲何有的改變,有的不改變呢?

這裏就涉及到咱們要講的深淺拷貝了:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#不可變數據類型:數字,字符串,元組         可變類型:列表,字典
 
# l=[2,2,3]
# print(id(l))
# l[0]=5
# print(id(l))   # 當你對可變類型進行修改時,好比這個列表對象l,它的內存地址不會變化,注意是這個列表對象l,不是它裏面的元素
#                # this is the most important
#
# s='alex'
# print(id(s))   #像字符串,列表,數字這些不可變數據類型,,是不能修改的,好比我想要一個'Alex'的字符串,只能從新建立一個'Alex'的對象,而後讓指針只想這個新對象
#
# s[0]='e'       #報錯
# print(id(s))
 
#重點:淺拷貝
a = [[ 1 , 2 ], 3 , 4 ]
b = a[:] #b=a.copy()
 
print (a,b)
print ( id (a), id (b))
print ( '*************' )
print ( 'a[0]:' , id (a[ 0 ]), 'b[0]:' , id (b[ 0 ]))
print ( 'a[0][0]:' , id (a[ 0 ][ 0 ]), 'b[0][0]:' , id (b[ 0 ][ 0 ]))
print ( 'a[0][1]:' , id (a[ 0 ][ 1 ]), 'b[0][1]:' , id (b[ 0 ][ 1 ]))
print ( 'a[1]:' , id (a[ 1 ]), 'b[1]:' , id (b[ 1 ]))
print ( 'a[2]:' , id (a[ 2 ]), 'b[2]:' , id (b[ 2 ]))
 
 
print ( '___________________________________________' )
b[ 0 ][ 0 ] = 8
 
print (a,b)
print ( id (a), id (b))
print ( '*************' )
print ( 'a[0]:' , id (a[ 0 ]), 'b[0]:' , id (b[ 0 ]))
print ( 'a[0][0]:' , id (a[ 0 ][ 0 ]), 'b[0][0]:' , id (b[ 0 ][ 0 ]))
print ( 'a[0][1]:' , id (a[ 0 ][ 1 ]), 'b[0][1]:' , id (b[ 0 ][ 1 ]))
print ( 'a[1]:' , id (a[ 1 ]), 'b[1]:' , id (b[ 1 ]))
print ( 'a[2]:' , id (a[ 2 ]), 'b[2]:' , id (b[ 2 ]))<br><br><br> #outcome
# [[1, 2], 3, 4] [[1, 2], 3, 4]
# 4331943624 4331943752
# *************
# a[0]: 4331611144 b[0]: 4331611144
# a[0][0]: 4297375104 b[0][0]: 4297375104
# a[0][1]: 4297375136 b[0][1]: 4297375136
# a[1]: 4297375168 b[1]: 4297375168
# a[2]: 4297375200 b[2]: 4297375200
# ___________________________________________
# [[8, 2], 3, 4] [[8, 2], 3, 4]
# 4331943624 4331943752
# *************
# a[0]: 4331611144 b[0]: 4331611144
# a[0][0]: 4297375328 b[0][0]: 4297375328
# a[0][1]: 4297375136 b[0][1]: 4297375136
# a[1]: 4297375168 b[1]: 4297375168
# a[2]: 4297375200 b[2]: 4297375200

那麼怎麼解釋這樣的一個結果呢?

  

 再不懂,俺就沒辦法啦...

列表補充:

b,*c=[1,2,3,4,5]

六 tuple(元組)

元組被稱爲只讀列表,即數據能夠被查詢,但不能被修改,因此,列表的切片操做一樣適用於元組。

元組寫在小括號(())裏,元素之間用逗號隔開。

雖然tuple的元素不可改變,但它能夠包含可變的對象,好比list列表。

構造包含 0 個或 1 個元素的元組比較特殊,因此有一些額外的語法規則:

?
1
2
tup1 = ()    # 空元組
tup2 = ( 20 ,) # 一個元素,須要在元素後添加逗號
做用:

1 對於一些數據咱們不想被修改,可使用元組;

2 另外,元組的意義還在於,元組能夠在映射(和集合的成員)中看成鍵使用——而列表則不行;元組做爲不少內建函數和方法的返回值存在。 

字典

# product_list=[
#     ('book',100),
#     ('Mac Pro',9000),
#     ('watch',500),
#     ('coffee',30),
#     ('Python',106),]
# 
# saving=input('input your saving:')
# shopping_car=[]
# 
# if saving.isdigit():
#     saving=int(saving)
#     while True:
#         for i,v in enumerate(product_list):
#             print(i,v)
#         user_choice=input('選擇購買商品編號[退出:q]:')
# 
#         if user_choice.isdigit():
#             user_choice=int(user_choice)
#             if user_choice<len(product_list) and user_choice>=0:
#                 product_item=product_list[user_choice]
#                 if product_item[1]<saving:
#                     saving-=product_item[1]
#                     shopping_car.append(product_item)
#                     print('您當前的餘額爲%s'%saving)
#             else:
#                 print('編號錯誤')
#         elif user_choice=='q':
#             print('---------您已經購買以下商品-----------')
#             for i in shopping_car:
#                 print(i)
#             print('您的餘額爲%s'%saving)
#             break
# 
#         else:
#             print('invalid choice')
購物車實例

七 Dictionary(字典)

字典是python中惟一的映射類型,採用鍵值對(key-value)的形式存儲數據。python對key進行哈希函數運算,根據計算的結果決定value的存儲地址,因此字典是無序存儲的,且key必須是可哈希的。可哈希表示key必須是不可變類型,如:數字、字符串、元組。

字典(dictionary)是除列表意外python之中最靈活的內置數據結構類型。列表是有序的對象結合,字典是無序的對象集合。二者之間的區別在於:字典當中的元素是經過鍵來存取的,而不是經過偏移存取。

建立字典:     

?
1
2
3
4
dic1 = { 'name' : 'alex' , 'age' : 36 , 'sex' : 'male' }
dic2 = dict ((( 'name' , 'alex' ),))
print (dic1)
print (dic2)

對應操做:

1 增

?
1
2
3
4
5
6
7
8
9
10
dic3 = {}
 
dic3[ 'name' ] = 'alex'
dic3[ 'age' ] = 18
print (dic3) #{'name': 'alex', 'age': 18}
 
a = dic3.setdefault( 'name' , 'yuan' )
b = dic3.setdefault( 'ages' , 22 )
print (a,b)
print (dic3)

2 查

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
dic3 = { 'name' : 'alex' , 'age' : 18 }
 
# print(dic3['name'])
# print(dic3['names'])
#
# print(dic3.get('age',False))
# print(dic3.get('ages',False))
 
print (dic3.items())
print (dic3.keys())
print (dic3.values())
 
print ( 'name' in dic3) # py2:  dic3.has_key('name')
print ( list (dic3.values()))

3 改

?
1
2
3
4
5
6
dic3 = { 'name' : 'alex' , 'age' : 18 }
 
dic3[ 'name' ] = 'alvin'
dic4 = { 'sex' : 'male' , 'hobby' : 'girl' , 'age' : 36 }
dic3.update(dic4)
print (dic3)

4 刪

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dic4 = { 'name' : 'alex' , 'age' : 18 , 'class' : 1 }
 
 
# dic4.clear()
# print(dic4)
del dic4[ 'name' ]
print (dic4)
 
a = dic4.popitem()
print (a,dic4)
 
# print(dic4.pop('age'))
# print(dic4)
 
# del dic4
# print(dic4)

5 其餘操做以及涉及到的方法

5.1 dict.fromkeys

?
1
2
3
4
5
6
7
8
9
10
d1 = dict .fromkeys([ 'host1' , 'host2' , 'host3' ], 'Mac' )
print (d1)
 
d1[ 'host1' ] = 'xiaomi'
print (d1)
#######
d2 = dict .fromkeys([ 'host1' , 'host2' , 'host3' ],[ 'Mac' , 'huawei' ])
print (d2)
d2[ 'host1' ][ 0 ] = 'xiaomi'
print (d2)

5.2  d.copy() 對字典 d 進行淺複製,返回一個和d有相同鍵值對的新字典

5.3  字典的嵌套

av_catalog = {
    "歐美":{
        "www.youporn.com": ["不少免費的,世界最大的","質量通常"],
        "www.pornhub.com": ["不少免費的,也很大","質量比yourporn高點"],
        "letmedothistoyou.com": ["可能是自拍,高質量圖片不少","資源很少,更新慢"],
        "x-art.com":["質量很高,真的很高","所有收費,屌比請繞過"]
    },
    "日韓":{
        "tokyo-hot":["質量怎樣不清楚,我的已經不喜歡日韓範了","據說是收費的"]
    },
    "大陸":{
        "1024":["所有免費,真好,好人一輩子平安","服務器在國外,慢"]
    }
}

av_catalog["大陸"]["1024"][1] += ",能夠用爬蟲爬下來"
print(av_catalog["大陸"]["1024"])
#ouput 
['所有免費,真好,好人一輩子平安', '服務器在國外,慢,能夠用爬蟲爬下來']
View Code

5.4 sorted(dict) : 返回一個有序的包含字典全部key的列表

?
1
2
dic = { 5 : '555' , 2 : '222' , 4 : '444' }
print ( sorted (dic)) 

5.5 字典的遍歷  

?
1
2
3
4
5
6
7
8
9
dic5 = { 'name' : 'alex' , 'age' : 18 }
 
for i in dic5:
     print (i,dic5[i])
 
for items in dic5.items():
     print (items)
for keys,values in dic5.items():
     print (keys,values)

  

 還用咱們上面的例子,存取這個班學生的信息,咱們若是經過字典來完成,那:

?
1
2
3
4
dic = { 'zhangsan' :{ 'age' : 23 , 'sex' : 'male' },
      '李四' :{ 'age' : 33 , 'sex' : 'male' },
      'wangwu' :{ 'age' : 27 , 'sex' : 'women' }  
      }

八 集合(set)

集合是一個無序的,不重複的數據組合,它的主要做用以下:

  • 去重,把一個列表變成集合,就自動去重了
  • 關係測試,測試兩組數據以前的交集、差集、並集等關係

集合(set):把不一樣的元素組成一塊兒造成集合,是python基本的數據類型。

集合元素(set elements):組成集合的成員(不可重複)

?
1
2
3
4
5
6
7
li = [ 1 , 2 , 'a' , 'b' ]
s = set (li)
print (s)    # {1, 2, 'a', 'b'}
 
li2 = [ 1 , 2 , 1 , 'a' , 'a' ]
s = set (li2)
print (s)  #{1, 2, 'a'}

集合對象是一組無序排列的可哈希的值:集合成員能夠作字典的鍵 

?
1
2
3
li = [[ 1 , 2 ], 'a' , 'b' ]
s = set (li) #TypeError: unhashable type: 'list'
print (s)

集合分類:可變集合、不可變集合

可變集合(set):可添加和刪除元素,非可哈希的,不能用做字典的鍵,也不能作其餘集合的元素

不可變集合(frozenset):與上面偏偏相反

?
1
2
3
li = [ 1 , 'a' , 'b' ]
s = set (li)
dic = {s: '123' } #TypeError: unhashable type: 'set'

集合的相關操做  

一、建立集合

     因爲集合沒有本身的語法格式,只能經過集合的工廠方法set()和frozenset()建立

?
1
2
3
4
5
6
s1 = set ( 'alvin' )
 
s2 = frozenset ( 'yuan' )
 
print (s1, type (s1))  #{'l', 'v', 'i', 'a', 'n'} <class 'set'>
print (s2, type (s2))  #frozenset({'n', 'y', 'a', 'u'}) <class 'frozenset'>

二、訪問集合

因爲集合自己是無序的,因此不能爲集合建立索引或切片操做,只能循環遍歷或使用in、not in來訪問或判斷集合元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
s1 = set ( 'alvin' )
print ( 'a' in s1)
print ( 'b' in s1)
#s1[1]  #TypeError: 'set' object does not support indexing
 
for i in s1:
     print (i)
#    
# True
# False
# v
# n
# l
# i
# a

三、更新集合

可以使用如下內建方法來更新:

s.add()
s.update()
s.remove()

注意只有可變集合才能更新:

?
1
2
3
4
5
6
7
8
9
10
11
12
# s1 = frozenset('alvin')
# s1.add(0)  #AttributeError: 'frozenset' object has no attribute 'add'
 
s2 = set ( 'alvin' )
s2.add( 'mm' )
print (s2)  #{'mm', 'l', 'n', 'a', 'i', 'v'}
 
s2.update( 'HO' ) #添加多個元素
print (s2)  #{'mm', 'l', 'n', 'a', 'i', 'H', 'O', 'v'}
 
s2.remove( 'l' )
print (s2)  #{'mm', 'n', 'a', 'i', 'H', 'O', 'v'}

del:刪除集合自己 

4、集合類型操做符 

1   in ,not in
2   集合等價與不等價(==, !=)
3   子集、超集

?
1
2
3
4
s = set ( 'alvinyuan' )
s1 = set ( 'alvin' )
print ( 'v' in s)
print (s1<s)

      4   聯合(|)

      聯合(union)操做與集合的or操做其實等價的,聯合符號有個等價的方法,union()。

?
1
2
3
4
5
s1 = set ( 'alvin' )
s2 = set ( 'yuan' )
s3 = s1|s2
print (s3)  #{'a', 'l', 'i', 'n', 'y', 'v', 'u'}
print (s1.union(s2)) #{'a', 'l', 'i', 'n', 'y', 'v', 'u'} 

五、交集(&)

與集合and等價,交集符號的等價方法是intersection()

?
1
2
3
4
5
6
s1 = set ( 'alvin' )
s2 = set ( 'yuan' )
s3 = s1&s2
print (s3)  #{'n', 'a'}
 
print (s1.intersection(s2)) #{'n', 'a'}

  六、查集(-)
      等價方法是difference()

?
1
2
3
4
5
6
s1 = set ( 'alvin' )
s2 = set ( 'yuan' )
s3 = s1 - s2
print (s3)  #{'v', 'i', 'l'}
 
print (s1.difference(s2)) #{'v', 'i', 'l'} 

七、對稱差集(^)

對稱差分是集合的XOR(‘異或’),取得的元素屬於s1,s2但不一樣時屬於s1和s2.其等價方法symmetric_difference()

?
1
2
3
4
5
6
s1 = set ( 'alvin' )
s2 = set ( 'yuan' )
s3 = s1^s2
print (s3)  #{'l', 'v', 'y', 'u', 'i'}
 
print (s1.symmetric_difference(s2)) #{'l', 'v', 'y', 'u', 'i'}

應用

?
1
2
3
'''最簡單的去重方式'''
lis = [ 1 , 2 , 3 , 4 , 1 , 2 , 3 , 4 ]
print list ( set (lis))    #[1, 2, 3, 4]

九 文件操做

9.1 對文件操做流程

  1. 打開文件,獲得文件句柄並賦值給一個變量
  2. 經過句柄對文件進行操做
  3. 關閉文件

     現有文件以下:     

?
1
2
3
4
5
6
7
昨夜寒蛩不住鳴。
驚回千里夢,已三更。
起來獨自繞階行。
人悄悄,簾外月朧明。
白首爲功名,舊山松竹老,阻歸程。
欲將心事付瑤琴。
知音少,絃斷有誰聽。
?
1
2
3
f = open ( '小重山' ) #打開文件
data = f.read() #獲取文件內容
f.close() #關閉文件

注意 if in the win,hello文件是utf8保存的,打開文件時open函數是經過操做系統打開的文件,而win操做系統

默認的是gbk編碼,因此直接打開會亂碼,須要f=open('hello',encoding='utf8'),hello文件若是是gbk保存的,則直接打開便可。

9.2 文件打開模式  

?
1
2
3
4
5
6
7
8
9
10
11
12
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     Character Meaning
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     'r'       open for reading (default)
     'w'       open for writing, truncating the file first
     'x'       create a new file and open it for writing
     'a'       open for writing, appending to the end of the file if it exists
     'b'       binary mode
     't'       text mode (default)
     '+'       open a disk file for updating (reading and writing)
     'U'       universal newline mode (deprecated)
     = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

先介紹三種最基本的模式:

?
1
2
3
4
5
# f = open('小重山2','w') #打開文件
# f = open('小重山2','a') #打開文件
# f.write('莫等閒1\n')
# f.write('白了少年頭2\n')
# f.write('空悲切!3')

9.3 文件具體操做

def read(self, size=-1): # known case of _io.FileIO.read
        """
        注意,不必定能全讀回來
        Read at most size bytes, returned as bytes.

        Only makes one system call, so less data may be returned than requested.
        In non-blocking mode, returns None if no data is available.
        Return an empty bytes object at EOF.
        """
        return ""

def readline(self, *args, **kwargs):
        pass

def readlines(self, *args, **kwargs):
        pass


def tell(self, *args, **kwargs): # real signature unknown
        """
        Current file position.

        Can raise OSError for non seekable files.
        """
        pass

def seek(self, *args, **kwargs): # real signature unknown
        """
        Move to new file position and return the file position.

        Argument offset is a byte count.  Optional argument whence defaults to
        SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
        are SEEK_CUR or 1 (move relative to current position, positive or negative),
        and SEEK_END or 2 (move relative to end of file, usually negative, although
        many platforms allow seeking beyond the end of a file).

        Note that not all file objects are seekable.
        """
        pass

def write(self, *args, **kwargs): # real signature unknown
        """
        Write bytes b to file, return number written.

        Only makes one system call, so not all of the data may be written.
        The number of bytes actually written is returned.  In non-blocking mode,
        returns None if the write would block.
        """
        pass

def flush(self, *args, **kwargs):
        pass


def truncate(self, *args, **kwargs): # real signature unknown
        """
        Truncate the file to at most size bytes and return the truncated size.

        Size defaults to the current file position, as returned by tell().
        The current file position is changed to the value of size.
        """
        pass


def close(self): # real signature unknown; restored from __doc__
            """
            Close the file.

            A closed file cannot be used for further I/O operations.  close() may be
            called more than once without error.
            """
            pass
##############################################################less usefull
    def fileno(self, *args, **kwargs): # real signature unknown
            """ Return the underlying file descriptor (an integer). """
            pass

    def isatty(self, *args, **kwargs): # real signature unknown
        """ True if the file is connected to a TTY device. """
        pass

    def readable(self, *args, **kwargs): # real signature unknown
        """ True if file was opened in a read mode. """
        pass

    def readall(self, *args, **kwargs): # real signature unknown
        """
        Read all data from the file, returned as bytes.

        In non-blocking mode, returns as much as is immediately available,
        or None if no data is available.  Return an empty bytes object at EOF.
        """
        pass

    def seekable(self, *args, **kwargs): # real signature unknown
        """ True if file supports random-access. """
        pass


    def writable(self, *args, **kwargs): # real signature unknown
        """ True if file was opened in a write mode. """
        pass
操做方法介紹
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
f = open ( '小重山' ) #打開文件
# data1=f.read()#獲取文件內容
# data2=f.read()#獲取文件內容
#
# print(data1)
# print('...',data2)
# data=f.read(5)#獲取文件內容
 
# data=f.readline()
# data=f.readline()
# print(f.__iter__().__next__())
# for i in range(5):
#     print(f.readline())
 
# data=f.readlines()
 
# for line in f.readlines():
#     print(line)
 
 
# 問題來了:打印全部行,另外第3行後面加上:'end 3'
# for index,line in enumerate(f.readlines()):
#     if index==2:
#         line=''.join([line.strip(),'end 3'])
#     print(line.strip())
 
#切記:之後咱們必定都用下面這種
# count=0
# for line in f:
#     if count==3:
#         line=''.join([line.strip(),'end 3'])
#     print(line.strip())
#     count+=1
 
# print(f.tell())
# print(f.readline())
# print(f.tell())#tell對於英文字符就是佔一個,中文字符佔三個,區分與read()的不一樣.
# print(f.read(5))#一箇中文佔三個字符
# print(f.tell())
# f.seek(0)
# print(f.read(6))#read後無論是中文字符仍是英文字符,都統一算一個單位,read(6),此刻就讀了6箇中文字符
 
#terminal上操做:
f = open ( '小重山2' , 'w' )
# f.write('hello \n')
# f.flush()
# f.write('world')
 
# 應用:進度條
# import time,sys
# for i in range(30):
#     sys.stdout.write("*")
#     # sys.stdout.flush()
#     time.sleep(0.1)
 
 
# f = open('小重山2','w')
# f.truncate()#所有截斷
# f.truncate(5)#所有截斷
 
 
# print(f.isatty())
# print(f.seekable())
# print(f.readable())
 
f.close() #關閉文件

接下來咱們繼續擴展文件模式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# f = open('小重山2','w') #打開文件
# f = open('小重山2','a') #打開文件
# f.write('莫等閒1\n')
# f.write('白了少年頭2\n')
# f.write('空悲切!3')
 
 
# f.close()
 
#r+,w+模式
# f = open('小重山2','r+') #以讀寫模式打開文件
# print(f.read(5))#可讀
# f.write('hello')
# print('------')
# print(f.read())
 
 
# f = open('小重山2','w+') #以寫讀模式打開文件
# print(f.read(5))#什麼都沒有,由於先格式化了文本
# f.write('hello alex')
# print(f.read())#仍是read不到
# f.seek(0)
# print(f.read())
 
#w+與a+的區別在因而否在開始覆蓋整個文件
 
 
# ok,重點來了,我要給文本第三行後面加一行內容:'hello 岳飛!'
# 有同窗說,前面不是作過修改了嗎? 大哥,剛纔是修改內容後print,如今是對文件進行修改!!!
# f = open('小重山2','r+') #以寫讀模式打開文件
# f.readline()
# f.readline()
# f.readline()
# print(f.tell())
# f.write('hello 岳飛')
# f.close()
# 和想的不同,無論事!那涉及到文件修改怎麼辦呢?
 
# f_read = open('小重山','r') #以寫讀模式打開文件
# f_write = open('小重山_back','w') #以寫讀模式打開文件
 
# count=0
# for line in f_read:
     # if count==3:
     #     f_write.write('hello,岳飛\n')
     #
     # else:
     #     f_write.write(line)
 
 
     # another way:
     # if count==3:
     #
     #     line='hello,岳飛2\n'
     # f_write.write(line)
     # count+=1
 
 
# #二進制模式
# f = open('小重山2','wb') #以二進制的形式讀文件
# # f = open('小重山2','wb') #以二進制的形式寫文件
# f.write('hello alvin!'.encode())#b'hello alvin!'就是一個二進制格式的數據,只是爲了觀看,沒有顯示成010101的形式

注意1:  不管是py2仍是py3,在r+模式下均可以等量字節替換,但沒有任何意義的! 

注意2:有同窗在這裏會用readlines獲得內容列表,再經過索引對相應內容進行修改,最後將列表從新寫會該文件。

           這種思路有一個很大的問題,數據若很大,你的內存會受不了的,而咱們的方式則能夠經過迭代器來優化這個過程。 

補充:rb模式以及seek

在py2中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#昨夜寒蛩不住鳴.
 
f = open ( 'test' , 'r' ,) #以寫讀模式打開文件
 
f.read( 3 )
 
# f.seek(3)
# print f.read(3) # 夜
 
# f.seek(3,1)
# print f.read(3) # 寒
 
# f.seek(-4,2)
# print f.read(3) # 鳴

在py3中:

複製代碼
# test: 
昨夜寒蛩不住鳴.

f = open('test','rb',) #以寫讀模式打開文件

f.read(3)

# f.seek(3)
# print(f.read(3)) # b'\xe5\xa4\x9c'

# f.seek(3,1)
# print(f.read(3)) # b'\xe5\xaf\x92'

# f.seek(-4,2)
# print(f.read(3))   # b'\xe9\xb8\xa3'

#總結: 在py3中,若是你想要字符數據,即用於觀看的,則用r模式,這樣我f.read到的數據是一個通過decode的
#     unicode數據; 可是若是這個數據我並不須要看,而只是用於傳輸,好比文件上傳,那麼我並不須要decode
#     直接傳送bytes就行了,因此這個時候用rb模式.

#     在py3中,有一條嚴格的線區分着bytes和unicode,好比seek的用法,在py2和py3裏都是一個個字節的seek,
#     但在py3裏你就必須聲明好了f的類型是rb,不容許再模糊.

#建議: 之後再讀寫文件的時候直接用rb模式,須要decode的時候仔顯示地去解碼.
複製代碼

9.4 with語句

爲了不打開文件後忘記關閉,能夠經過管理上下文,即:

?
1
2
with open ( 'log' , 'r' ) as f:
         pass

如此方式,當with代碼塊執行完畢時,內部會自動關閉並釋放文件資源。

在Python 2.7 後,with又支持同時對多個文件的上下文進行管理,即:

?
1
2
with open ( 'log1' ) as obj1, open ( 'log2' ) as obj2:
     pass
相關文章
相關標籤/搜索