2.9. 具名元組(namedtuple)(暫不懂,懶得看) 15
序列是python中最基本的數據結構.序列中的每個元素都分配一個數字-它的位置,或索引,第一個索引是0,第二個索引是1,依此類推.
python有6個序列的內置類型,但最常見的是列表和元組.
序列都可以進行的操作包括索引,切片,加,乘,檢查成員.
此外,python已經內置確定序列的長度以及確定最大和最小的元素的方法.
列表時最長的python數據類型,他可以作爲一個方括號內的逗號分隔值出現.
列表的數據項不需要具有相同的類型.
創建一個列表,只要把逗號分隔的不同的數據項使用方括號括起來即可,如下所示:
list1=[1,2,3,4]
與字符串的索引一樣,列表索引從0開始,列表可以進行截取,組合燈操作.
使用下標索引來訪問列表中的值,同樣你也可以使用方括號的形式截取字符
list1=['Google','Runoob',1997,2000];
list2=[1,2,3,4,5,6,7];
print("list1[0]:",list1[0])
print("list2[1:5]:",list2[1:5])
list1[0]:Google
list2[1:5]:[2,3,4,5]
你可以對列表的數據項進行修改或更新,你也可以使用append()方法來添加列表項
list=['Google','Runoob',1997,2000]
print("第三個元素爲:",list[2])
list[2]=2001
print("更新後的第三個元素爲:",list[2])
第三個元素爲:1997
更新後的第三個元素爲:2001
可以使用del語句來刪除列表的元素
list=['Google','Runoob',1997,2000]
print("原始列表:",list)
del list[2]
print("刪除第三個元素:",list)
原始列表:['Google','Runoob',1997,2000]
刪除第三個元素:['Google','Runoob',2000]
列表對+和*的操作符與字符串相似.
len([1,2])3長度
[1,2]+[3,4][1,2,3,4]組合
['hi']*4['hi','hi','hi','hi']重複
2 in[1,2]True元素是否存在列表中
for x in[1,2,3]:print(x,end="")1 2 3迭代#for循環是迭代循環,後會細講
Python的列表截取與字符串操作類型,如下所示:
L=['Google','Runoob','Taobao']
操作:
Python表達式 結果 描述
L[2] 'Taobao' 讀取第三個元素
L[-2] 'Runoob' 從右側開始讀取倒數第二個元素:count from the right
L[1:] ['Runoob','Taobao'] 輸出從第二個元素開始後的所有元素
>>>L=['Google','Runoob','Taobao']
>>>L[2]
'Taobao'
>>>L[-2]
'Runoob'
>>>L[1:]
['Runoob','Taobao']
>>>
列表還支持拼接操作:
>>>squares=[1,4,9,16,25]
>>>squares+=[36,49,64,81,100]
>>>squares
[1,4,9,16,25,36,49,64,81,100]
>>>
使用嵌套列表即在列表裏創建其他列表:
>>>a=['a','b','c']
>>>n=[1,2,3]
>>>x=[a,n]
>>>x
[['a','b','c'],[1,2,3]]
>>>x[0]
['a','b','c']
>>>x[0][1]
'b'
列表函數len(list):列表元素個數
max(list):返回列表元素最大值
min(list):返回列表元素最小值
list(seq):將元組轉換爲列表
列表方法append(obj):在列表末尾添加新的對象
count(obj):統計某個元素在列表中出現的次數
extend(seq):在列表末尾一次性追加另一個序列中的多個值(用新列表擴展原來的列表)
index(obj):從列表彙總找出某個值第一個匹配項的索引位置
insert(index,obj):將對象插入列表
pop([index=-1]):移除列表中的一個元素(默認最後一個元素),並且返回該元素的值,index是可選項
remove(obj):移除列表中某個值的第一個匹配項
reverse():反向列表中元素
sort(cmp=None,key=None,reverse=False):對原列表進行排序,可以使用匿名函數修改排序的規則,後會細講
clear():清空列表
copy():複製列表
python創建二維列表,將需要的參數寫入cols和rows即可
list_2d=[[0 for col in range(cols)]for row in range(rows)]
實例:
>>>list_2d=[[0 for i in range(5)]for i in range(5)]
>>>list_2d[0].append(3)
>>>list_2d[0].append(5)
>>>list_2d[2].append(7)
>>>list_2d
[[0,0,0,0,0,3,5],[0,0,0,0,0],[0,0,0,0,0,7],[0,0,0,0,0],[0,0,0,0,0]]
列表的複製有三種方法,首先設a=[1,2,3,4],第一種a=b,第二種c=[];c=a,第三種d=a[:],前兩種都是單純的把b,c引向a的內存地址,而第四種則是獲取a的所有元素.
>>>a=[1,2,3]
>>>b=a
>>>c=[]
>>>c=a
>>>d=a[:]
>>>a,b,c,d
([1,2,3],[1,2,3],[1,2,3],[1,2,3])
>>>b[0]='b'
>>>a,b,c,d
(['b',2,3],['b',2,3],['b',2,3],[1,2,3])
>>>id(a),id(b),id(c),id(d)
(140180778120200,140180778120200,140180778120200,140180778122696)
>>>c[0]='c'
>>>a,b,c,d
(['c',2,3],['c',2,3],['c',2,3],[1,2,3])
>>>id(a),id(b),id(c),id(d)
(140180778120200,140180778120200,140180778120200,140180778122696)
>>>d[0]='d'
>>>a,b,c,d
(['c',2,3],['c',2,3],['c',2,3],['d',2,3])
>>>id(a),id(b),id(c),id(d)
(140180778120200,140180778120200,140180778120200,140180778122696)
可以看到a b c三個是同一id值,當改變當中任一列表元素的值後,三者會同步改變。
但d的元素值不會變,改變d的元素值其它三個變量內的元素值也不會變。
從a b c d的id值來看,a b c地址全一樣,唯有d分配了新地址。
所以一般情況下想複製得到一個新列表並改變新列表內元素而不影響原列表,可以採用d的賦值方式。
這只是針對這種比較單一的普通列表。
使用copy模塊可以複製一個內存地址不同的列表.
import copy
a=[1,2,3,4]
b=copy.copy(a)
id(a),id(b)#a和b的內存地址不同
使用列表自帶方法copy()複製一個不同內存地址的列表:
a=[1,2,3,4]
b=a.copy()
id(a),id(b)#a和b的內存地址不同
有時在取list中元素時可能會遇到以下情形:
>>>a=[]
>>>a[0]
Traceback(most recent call last):
File"<stdin>",line 1,in<module>
IndexError:list index out of range
這種情況發生是因爲只定義了一個空列表,沒有進行任何的賦值,所以列表裏什麼也沒有,而後面的報錯也明確表示了索引超出範圍,即寫上的0
其實是第一位值的位置,而此時是空列表沒有賦值,故而報錯。
而如果我們使用以下語句則不會報錯:
>>>a[0:]
[]
這個不是什麼小技巧,這是不一樣的語句意義,這句話其實是把這個列表a裏的所有值都輸出,其效果和下面表達的最終結果是一致的。
>>>a[:]
[]
而這個語句並不能避免上面報錯中超出索引範圍的錯誤,這個根本就是兩種不同的意義的語句。a[0:]和a[:]在腳本輸出時相當於print(a)
的意思。這不是解決錯誤的方式,不能將它當成trick來用。
我不知道以後會不會講,看到了就拷貝給你們看:
1、列表推導式書寫形式:
[表達式for變量in列表]
或者
[表達式for變量in列表if條件]
2、舉例說明:
#!/usr/bin/python
#-*-coding:utf-8-*-
li=[1,2,3,4,5,6,7,8,9]
print([x**2 for x in li])
print([x**2 for x in li if x>5])
print(dict([(x,x*10)for x in li]))
print([(x,y)for x in range(10)if x%2 if x>3 for y in range(10)if y>7 if y!=8])
vec=[2,4,6]
vec2=[4,3,-9]
sq=[vec[i]+vec2[i]for i in range(len(vec))]
print(sq)
print([x*y for x in[1,2,3]for y in[1,2,3]])
testList=[1,2,3,4]
def mul2(x):
return x*2
print([mul2(i)for i in testList])
結果:
[1,4,9,16,25,36,49,64,81]
[36,49,64,81]
{1:10,2:20,3:30,4:40,5:50,6:60,7:70,8:80,9:90}
[(5,9),(7,9),(9,9)]
[6,7,-3]
[1,2,3,2,4,6,3,6,9]
[2,4,6,8]
3、總結:
我覺得就是通過for語句處理表達式裏面的變量,如果還要加條件,就加if條件就可以了。
python的元組與列表類似,不同之處在於元組的元素不能修改.
元組使用小括號,列表使用方括號.
元組創建很簡單,只需要在括號中添加元素,並使用逗號隔開即可.
>>>tup1=('Google','Runoob',1997,2000);
>>>tup2=(1,2,3,4,5);
>>>tup3="a","b","c","d";#不需要括號也可以
>>>type(tup3)
<class'tuple'>
注意:元組中只包含一個元素時,需要在元素後面添加逗號,否則括號會被當做運算符使用
>>>tup1=(50)
>>>type(tup1)#不加逗號,類型爲整型
<class'int'>
>>>tup1=(50,)
>>>type(tup1)#加上逗號,類型爲元組
<class'tuple'>
元組可以使用下標索引來訪問元組中的值
tup1=('Google','Runoob',1997,2000)
tup2=(1,2,3,4,5,6,7)
print("tup1[0]:",tup1[0])
print("tup2[1:5]:",tup2[1:5])
tup1[0]:Google
tup2[1:5]:(2,3,4,5)
元組中的元素值是不允許修改的,但我們可以對元組進行連接組合
tup1=(12,34.56);
tup2=('abc','xyz')
#以下修改元組元素操作是非法的。
#tup1[0]=100
#創建一個新的元組
tup3=tup1+tup2;
print(tup3)
(12,34.56,'abc','xyz')
元組中的元素是不允許刪除的,但我們可以使用del語句來刪除整個元組
tup=('Google','Runoob',1997,2000)
print(tup)
del tup;
print("刪除後的元組tup:")
print(tup)
刪除後的元組tup:
Traceback(most recent call last):
File"test.py",line 8,in<module>
print(tup)
NameError:name'tup'is not defined
同列表因此複製粘貼:
與字符串一樣,元組之間可以使用+號和*號進行運算。這就意味着他們可以組合和複製,運算後會生成一個新的元組。
Python表達式 結果 描述
len((1,2,3)) 3 計算元素個數
(1,2,3)+(4,5,6) (1,2,3,4,5,6) 連接
('Hi!',)*4 ('Hi!','Hi!','Hi!','Hi!') 複製
3 in(1,2,3) True 元素是否存在
for x in(1,2,3):print(x,) 1 2 3 迭代
同列表,因此複製粘貼:
因爲元組也是一個序列,所以我們可以訪問元組中的指定位置的元素,也可以截取索引中的一段元素,如下所示:
元組:
L=('Google','Taobao','Runoob')
Python表達式 結果 描述
L[2] 'Runoob' 讀取第三個元素
L[-2] 'Taobao' 反向讀取;讀取倒數第二個元素
L[1:] ('Taobao','Runoob') 截取元素,從第二個開始後的所有元素。
運行實例如下:
>>>L=('Google','Taobao','Runoob')
>>>L[2]
'Runoob'
>>>L[-2]
'Taobao'
>>>L[1:]
('Taobao','Runoob')
len(tuple):計算元組元素個數
max(tuple):返回元祖中元素最大值
min(tuple):返回元組中元素最小值
tuple(seq):將列表轉換爲元組
>>>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包含的3個元素:當我們把list的元素'A'和'B'修改爲'X'和'Y'後,tuple變爲:表面上看,tuple的元素確實變了,但其實變的不是tuple的元素,而是list的元素。tuple一開始指向的list並沒有改成別的list,所以,tuple所謂的"不變"是說,tuple的每個元素,指向永遠不變。即指向'a',就不能改成指向'b',指向一個list,就不能改成指向其他對象,但指向的這個list本身是可變的!理解了"指向不變"後,要創建一個內容也不變的tuple怎麼做?那就必須保證tuple的每一個元素本身也不能變。
有興趣的自行研究!!!
Python元組的升級版本--namedtuple(具名元組)
因爲元組的侷限性:不能爲元組內部的數據進行命名,所以往往我們並不知道一個元組所要表達的意義,所以在這裏引入了collections.namedtuple這個工廠函數,來構造一個帶字段名的元組。具名元組的實例和普通元組消耗的內存一樣多,因爲字段名都被存在對應的類裏面。這個類跟普通的對象實例比起來也要小一些,因爲Python不會用__dict__來存放這些實例的屬性。
namedtuple對象的定義如以下格式:
collections.namedtuple(typename,field_names,verbose=False,rename=False)
返回一個具名元組子類typename,其中參數的意義如下:
typename:元組名稱
field_names:元組中元素的名稱
rename:如果元素名稱中含有python的關鍵字,則必須設置爲rename=True
verbose:默認就好
下面來看看聲明一個具名元組及其實例化的方法:
import collections
#兩種方法來給namedtuple定義方法名
#User=collections.namedtuple('User',['name','age','id'])
User=collections.namedtuple('User','name age id')
user=User('tester','22','464643123')
print(user)
collections.namedtuple('User','name age id')創建一個具名元組,需要兩個參數,一個是類名,另一個是類的各個字段名。後者可以是有多個字符串組成的可迭代對象,或者是有空格分隔開的字段名組成的字符串(比如本示例)。具名元組可以通過字段名或者位置來獲取一個字段的信息。
輸出結果:
User(name='tester',age='22',id='464643123')
具名元組的特有屬性:
類屬性_fields:包含這個類所有字段名的元組類方法_make(iterable):接受一個可迭代對象來生產這個類的實例實例方法_asdict():把具名元組以collections.OrdereDict的形式返回,可以利用它來把元組裏的信息友好的展示出來
from collections import namedtuple
#定義一個namedtuple類型User,幷包含name,sex和age屬性。
User=namedtuple('User',['name','sex','age'])
#創建一個User對象
user=User(name='Runoob',sex='male',age=12)
#獲取所有字段名
print(user._fields)
#也可以通過一個list來創建一個User對象,這裏注意需要使用"_make"方法
user=User._make(['Runoob','male',12])
print(user)
#User(name='user1',sex='male',age=12)
#獲取用戶的屬性
print(user.name)
print(user.sex)
print(user.age)
#修改對象屬性,注意要使用"_replace"方法
user=user._replace(age=22)
print(user)
#User(name='user1',sex='male',age=21)
#將User對象轉換成字典,注意要使用"_asdict"
print(user._asdict())
#OrderedDict([('name','Runoob'),('sex','male'),('age',22)])
以上實例輸出結果爲:
('name','sex','age')
User(name='Runoob',sex='male',age=12)
Runoob
male
12
User(name='Runoob',sex='male',age=22)
OrderedDict([('name','Runoob'),('sex','male'),('age',22)])
可以先使用list()將元組轉換成列表,然後對列表進行修改,之後再將列表用tuple()轉化成元組.其次,也可也使用元組的'+'拼接對元組的值進行增加.