确定蛋白浓度(四)|自学生信Python(第二十四天)
创建一个空表
先创建一个空表对于某些计算十分有利。 例如,当想给二维矩阵计算特征值时,可以先将计数表用零填满。 创建一维零列表可以用如下方式完成:
>>> row = [ 0 ] * 6
[0,0,0,0,0,0]
可以通过重复循环创建多行:
table = []
for i in range(6):
table.append([0]*6)
或者以列表推导式:
>>> table = [[0]*6 for i in range(6)]
注意不要写成:
>>> row = [0] * 3
>>> table = [row] * 3
>>> tabl e
[[0,0,0],[0,0,0],[0,0,0]]
在结果表中,这些行不会是空行的副本,而是引用了同一行。 因此, 所产生的表包含三个同一列表对象。每次改变结果表中的任意一列的单元格数值,所有其他行中的单元格会同时改变。 为了说明这一点,可尝试以下操作:
>>> table [0] [1] = 5
>>> table
[[0,5,0],[0,5,0],[0,5,0]]
用字典表示表
当使用嵌套列表的表时,需要知道单元格的数值索引,有时这会使代码难以阅读。而且列表虽便于排序但不便于搜索。 那么是否有其他的替代方案呢?
使用字典替代列表
字典便于搜索或查阅信息。 蛋白质和消光数据可用一个字典列表来表示:
table = [
{'protein': 0.16,'ext1':0.038,'ext2':0.044,'ext3':0.040},
{'protein': 0.33,'ext1':0.089,'ext2':0.095,'ext3':0.091},
{'protein':0.66,'ext1':0.184,'ext2':0.191,'ext3':0.191},
{'protein':1.00,'ext1':0.280,'ext2':0.292,'ext3':0.283},
{'protein':1.32,'ext1':0.365,'ext2':0.367,'ext3':0.365},
{'protein':1.66,'ext1':0.441,'ext2 ':0.443,'ext3':0.444}
]
外列表中所包含的每一行都是由数个含有数据的列标签所组成的字典。 这种访问单元 格的方式使代码变得更易读:
cell = table [1] ['ext2' ]
字典中嵌套字典
如果每行也都有明确的标签,就可以用字典中的字典来表示一个表。以 Lowry 的数据 为例,每行必须添加 ID 号:
table = [
'row1':{'protein': 0.16,'ext1':0.038,'ext2':0.044,'ext3':0.040},
'row2':{'protein': 0.33,'ext1':0.089,'ext2':0.095,'ext3':0.091},
'row3':{'protein':0.66,'ext1':0.184,'ext2':0.191,'ext3':0.191},
'row4':{'protein':1.00,'ext1':0.280,'ext2':0.292,'ext3':0.283},
'row5':{'protein':1.32,'ext1':0.365,'ext2':0.367,'ext3':0.365},
'row6':{'protein':1.66,'ext1':0.441,'ext2 ':0.443,'ext3':0.444}
]
有了这样的嵌套字典,查找特定的单元格会更加快捷简单:
cell = tab1e['row1'] ['ext2']
或者也可以用以下两种方法:
· 将列表放入字典。 仍可以很容易地搜索给定项,只是每行中的数据格式更加简单。
· 将每列做成单独的列表。实际上是将该表旋转了 90° ,这更有利于做计算,比如计算几列数的平均值。但这种方法使得不能对行进行排序。
问答: 想搜索表也想排序表该怎么办?
可以将表存储为一个嵌套列表,并创建一个额外的字典用于搜索。用来加速程序运行的搜索字典又称为索引 ,使用含有数据的列表和一个额外的具有相同数据的字典进行搜索,会产生冗余。只要列表被更改,字典就会过期,需要更新,这将是产生非常讨厌的程序错误的潜在来源。一种可行的方式是使用专用类来存储数据。另一种使用索引的方法是使用 SQL 数据库,当有大量的数据时尤为有效。
如何转换表的表现形式
所有用于存储表的方法:嵌套列表、嵌套字典、二者混合(见图 7. 3) ,都有其特殊的优点及缺点。 表的不同表现形式的利弊在后面讨论。 通常情况下没有哪个表现形式能完全适合完成想做的一切,因此可能需要将表的一种表现形式转化为另一种。
要将嵌套列表转换成嵌套字典,单个 for 循环就足够了。在每次循环中,表示一行的一 个新字典将被添加到存储行的整体字典中,并引人计数器来命名行。
table = [
['protein','ext1','ext2','ext3'],
[0.16, 0.038,0.044,0.040],
[0.33,0.089,0.095,0.091],
[0.66,0.184,0.191,0.191],
[1.00,0.280,0,292,0.283],
[1. 32,0.365,0.367,0.365],
[1. 66,0.441,0.443,0.444]
]
nested_ dict = {}
n = 0
key = table[0]
# to include the header, run the for loop over
# ALL table elements (including the first one)
for row in table[1:]:
n = n + 1
entry = {key[0]:row[0],key[1]: row[1],key[2]:row[2],key [3]:row[3]}
nested_dict['row'+str(n)] = entry
print (nested_dict)
嵌套字典转换成嵌套列表也可以由单循环完成。 代码看起来与前例类似, 唯一的不同 在于索引被替换成字典的键。 在下面的例子中, nested_dict 是前例中创建的字典。
neated_list = []
for entry in nested_dict:
key = nested_dict[entry]
nested_list.append([key['protein'],key['ext1'],key['ext2',key['ext3']])
print (nested_list)