1. 程式人生 > >python 多行排序,根據染色體號,位置資訊排序,升序降序排序

python 多行排序,根據染色體號,位置資訊排序,升序降序排序

遇到一個問題是需要將檔案按照染色體編號和位置編號進行排序,在shell中我們可以使用sort -V -k2,3 annovar.xls這種方式來進行排序,而在python中如果想要進行多行排序,就需要sort的key引數指定的函式返回一個元組或者列表來進行排序。

現在我們有一個染色體位置檔案如下:

如果想要對上述的檔案進行排序,那麼key函式就可以像下面這樣寫:

def chrome_sort(key):
    '''
    染色體排序
    '''
    if key[0] == 'X':
        chrome = 24
    elif key[0] == 'Y':
        chrome = 25
    else:
        chrome = int(key[0])
    position = int(key[1])
    return (chrome,position)

使用這個函式,我們就可以將包含檔案每一行的列表進行排序了,完整程式碼如下:

#!/usr/bin/env python
# -*- coding=utf-8 -*-
import sys
import os

def chrome_sort(key):
    '''
    染色體排序
    '''
    if key[0] == 'X':
        chrome = 24
    elif key[0] == 'Y':
        chrome = 25
    else:
        chrome = int(key[0])
    position = int(key[1])
    return (chrome,position)

if __name__ == '__main__':
    f = sys.argv[1]
    ofile = sys.argv[2]
    assert len(sys.argv) == 3,'該指令碼接收兩個必選引數!'
    if os.path.exists(ofile):
        raise Exception('輸出檔案已經存在!')

    with open(f,'r') as indata,\
    open(ofile,'w') as odata:
        all_line_list = []
        for line in indata:
            line_list = line.strip().split()
            all_line_list.append(line_list)

        all_line_list.sort(key=chrome_sort)
        for i in all_line_list:
            odata.write('\t'.join(i)+'\n')

然後就能得到排序好的結果了,如下所示:

另一個問題,如果我們想要對其中一列進行正向排序,另一列進行反向排序怎麼辦呢?解決辦法非常簡單,就是將反向排序的那一列的返回值加一個負號,如下所示,還是剛才的例子:

def chrome_sort(key):
    '''
    染色體排序
    '''
    if key[0] == 'X':
        chrome = 24
    elif key[0] == 'Y':
        chrome = 25
    else:
        chrome = int(key[0])
    position = int(key[1])
    return (chrome,-position)#給postion新增一個負號即可

 得到的結果將是,第一列按照染色體號進行排序,第二列按照位置的倒序進行排序