本文實例講述了Python將名稱映射到序列元素中的方法。分享給大家供大家參考,具體如下:
問題:希望通過名稱來訪問元素,減少結構中對位置的依賴性
解決方案:使用命名元組collections.namedtuple()
。它是一個工廠方法,返回的是python中標準元組類型的子類,提供給它一個類型名稱以及相應的字段名稱,它就返回一個可實例化的類,為你以定義好的字段名稱傳入值等。
命名元組的主要作用在于將代碼同它所控制的元素位置間進行解耦
1
2
3
4
5
6
7
8
9
|
>>> from collections import namedtuple >>> Sub = namedtuple( 'Subscriber' ,[ 'addr' , 'joined' ]) >>> subscriber >>> subscriber.addr >>> subscriber.joined '2016-8-7' |
namedtuple
的實例與普通的元組是可互換的,而且支持所有普通元組所支持的操作,例如索引和分解(unpacking).
1
2
3
4
5
6
7
8
|
>>> len (subscriber) 2 >>> addr,joined = subscriber >>> addr >>> joined '2016-8-7' >>> |
使用普通元組的代碼:
1
2
3
4
5
|
def compute_cost(records): total = 0.0 for rec in records: total + = rec[ 1 ] * rec[ 2 ] return total |
通過位置來引用元素使得代碼的表達力不夠,而且也依賴于記錄的具體結構。
下面是使用命名元組的版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# example.py from collections import namedtuple Stock = namedtuple( 'Stock' , [ 'name' , 'shares' , 'price' ]) def compute_cost(records): total = 0.0 for rec in records: s = Stock( * rec) total + = s.shares * s.price return total # Some Data records = [ ( 'GOOG' , 100 , 490.1 ), ( 'ACME' , 100 , 123.45 ), ( 'IBM' , 50 , 91.15 ) ] print (compute_cost(records)) |
運行結果:
1
|
65912.5 |
補充:
如果要構建涉及字典的大型數據結構,使用namedtuple會更加有效。但是注意,與字典不同的是,namedtuple是不可變的。例如:
1
2
3
4
5
6
7
8
9
|
>>> s = Stock( 'ACMS' , 100 , 123.45 ) >>> s Stock(name = 'ACMS' , shares = 100 , price = 123.45 ) >>> s.shares = 75 Traceback (most recent call last): File "<pyshell#2>" , line 1 , in <module> s.shares = 75 AttributeError: can't set attribute >>> |
若要修改屬性,可使用namedtuple實例的_replace()
方法來實現。該方法會創建一個全新的命名元組,并對相應的值做替換;
1
2
3
4
|
>>> s = s._replace(shares = 75 ) >>> s Stock(name = 'ACMS' , shares = 75 , price = 123.45 ) >>> |
_replace()
方法一個微妙的用途是它可以作為一種簡便的方法填充具有可選或缺失字段的命名元組。
步驟:
1、創建一個包含默認值的“原型”元組;
2、使用_replace()
方法創建一個新實例,把相應的值替換掉;
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from collections import namedtuple Stock = namedtuple( 'Stock' , [ 'name' , 'shares' , 'price' , 'date' , 'time' ]) #創建一個包含默認值的“原型”元組 stock_prototype = Stock('', 0 , 0.0 , None , None ) #創建一個函數實現將字典轉化為Stock類型 def dict_to_stock(s): return stock_prototype._replace( * * s) a = { 'name' : 'ACMS' , 'shares' : 100 , 'price' : 123.45 } print (dict_to_stock(a)) b = { 'name' : 'ACMS' , 'shares' : 100 , 'price' : 123.45 , 'date' : '2016-08-08' } print (dict_to_stock(b)) c = { 'name' : 'ACMS' , 'price' : 123.45 } print (dict_to_stock(c)) |
運行結果:
1
2
3
|
Stock(name = 'ACMS' , shares = 100 , price = 123.45 , date = None , time = None ) Stock(name = 'ACMS' , shares = 100 , price = 123.45 , date = '2016-08-08' , time = None ) Stock(name = 'ACMS' , shares = 0 , price = 123.45 , date = None , time = None ) |
注意:如果我們的目標是定義一個高效的數據結構,而且將來會修改各種實例屬性,那么不推薦namedtuple!
(代碼摘自《Python Cookbook》)
希望本文所述對大家Python程序設計有所幫助。
原文鏈接:http://www.cnblogs.com/apple2016/p/5747656.html