2007-08-31

 

Python Cookbook 4.7 在2维列表中删除或重排某些列

需求:

你有一个二维列表,需要重新获得一个列表,其中行不变,而将某些列重排或者删除.

讨论:

使用列表递推式可以处理这个问题,比如你有如下的列表:

listOfRows = [ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]

现在你需要将第二列删除,并将第四列和第三列互换位置,用一个列表递推式就能出色的完成任务:

newList = [ [row[0], row[3], row[2]] for row in listOfRows ]

结果如下:

[[1, 4, 3], [5, 8, 7], [9, 12, 11]]

另外的办法,稍微复杂一些,是使用临时的列表来保存要调整的位置:

newList = [ [row[ci] for ci in (0, 3, 2)] for row in listofRows ]

我经常使用列表的列表来表示二维数组,而在处理这类问题的过程中经常遇到列的处理,比如重排某些列,忽略其中的一些数值等.使用列表递推式来处理这一类问题看起来不是那么显然.
列表递推式创建一个新列表,而不是改变原来的.但是即使你需要修改现有的列表,使用列表递推式然后赋值给现有列表也是很好的方法.比如,你想修改listOfRows,就按照本节的需求,你可能这样写:

listOfRows[:] = [ [row[0], row[3], row[2]] for row in listOfRows ]

但是请注意,遇到这样的问题,请是用本节给出的第二个列子的办法,用一个临时列表保存列的位置,而不是硬编码.也许你不喜欢将两个递推式嵌套起来,但是它会更安全一些.如果你使用这种方法,还能得到附加的好处,因为增强的灵活性,你可以将它封装成一个函数,将想要调整的顺序做为参数传递进去:

def pick_and_reorder_columns(listofRows, column_indexes):
    return [ [row[ci] for ci in column_indexes] for row in listofRows ]
columns = 0, 3, 2
newListOfPandas = pick_and_reorder_columns(oldListOfPandas, columns)
newListOfCats = pick_and_reorder_columns(oldListOfCats, columns)

上面的代码和前面的 一样,调整了列表中列的顺序,但是它操作的是两个列表.
最后要注意的,有些人喜欢将列表递推式中的变量部分替换成函数返回值,而不是直接使用,比如在:

[row[ci] for ci in column_indexes]

可以使用map函数,用__getitem__来代替[],所以可以这样写:

map(row._ _getitem_ _, column_indexes)

取决于你的Python版本,也许map版的会更快一些.不过我坚持认为最简单的列表递推式是最好的 .


Comments: 发表评论



<< Home

This page is powered by Blogger. Isn't yours?