學習python記錄---基礎

轉載過來的,方便記錄查看

原地址  http://www.cnblogs.com/yuanchenqi/articles/5782764.html 

沒有看到不讓轉載,所以如果作者看到不讓轉載請通知我,謝謝!

數據類型

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

一 Number(數字)

1.1 數字類型的創建

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

 

注意這裏與C的不同:

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 = 1;
    int = a;
    printf ("a:adr:%p,val:%d,b:adr:%p,val:%d\n",&a,a,&b,b);
    = 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"等等。

請注意,''""本身只是一種表示方式,不是字符串的一部分,因此,字符串'abc'只有abc這3個字符。如果'本身也是一個字符,那就可以用""括起來,比如"I'm OK"包含的字符是I'm,空格,OK這6個字符。

2.1 創建字符串:

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

對應操作:

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 中的小寫字母爲大寫

三 字節類型(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表示布爾值(請注意大小寫)

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

與或非操作:

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], 11, [21, [12]]] 
>>> x.count(1
2 
>>> x.count([1,2]) 
1

5.2 extend

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

1
2
3
4
5
>>> a = [123
>>> b = [456
>>> a.extend(b) 
>>> a 
[123456

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

1
2
3
4
5
6
7
8
9
10
>>> a = [123
>>> b = [456
>>> a.extend(b) 
>>> a 
[123456
>>> 
>>> a + 
[123456456
>>> a 
[123456

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
= [462179]
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 
['全部免費,真好,好人一生平安', '服務器在國外,慢,可以用爬蟲爬下來']

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 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']
=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']
=set(li) #TypeError: unhashable type: 'list'
print(s)

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

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

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

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

集合的相關操作  

1、創建集合

     由於集合沒有自己的語法格式,只能通過集合的工廠方法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'>

2、訪問集合

由於集合本身是無序的,所以不能爲集合創建索引或切片操作,只能循環遍歷或使用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 in s1:
    print(i)
#    
# True
# False
# v
# n
# l
# i
# a

3、更新集合

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

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:刪除集合本身 

四、集合類型操作符 

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'} 

5、交集(&)

與集合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'}

  6、查集(-)
      等價方法是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'} 

7、對稱差集(^)

對稱差分是集合的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
= 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
= 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上操作:
= 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
#昨夜寒蛩不住鳴.
 
= 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章