2014-07-17 93 views
0

我是Python新手。我有一个包含3列的文本文件,第一列包含数字。我想按递增顺序对这个txt的行进行排序。我试过这个:根据Python中的第一列对文本文件进行排序

lines=[line for line in inputFile if line.strip()] 
lines.sort() 

但是,文件按非数字排序,但按字母顺序排序。例如1,11,12,13,14,... 19,2,21 ....我怎样才能解决这个问题?

谢谢。

+3

是否有任何东西阻止您将每行转换为(数字,字符串,字符串)的元组,然后对该列表进行排序? – arknave

+0

我忘了提及:第一列中还有X和Y值,所以我不能将它们看作数字,字符串,字符串。 –

+0

请提供一些示例输入,以便我们确切知道您在说什么。 – jwd

回答

1

我不知道你所说的“列”(顺便说一句,如果是什么意思它是一个csv或tsv文件,检查标准库中的csv模块),但arknave的评论是正确的答案。甲简单化,幼稚和脆实现(假设制表符分隔值):

def convert(line): 
    x, y, z = line.strip().split("\t") 
    if x.isdigit(): 
     x = int(x) 
    return x, y, z 

lines = sorted(convert(line) for line in infile if line.strip()) 

CAVEAT:这依赖于CPython的2.7的实现细节并作为与另一种蟒版本或实施预期(AFAIK它可能无法工作将与CPython 3.x打破)。

更健壮的(但可能更慢)的解决方案:

def mycmp(t1, t2): 
    x, y = t1[0], t2[0] 
    x_int = x.isdigit() 
    y_int = y.isdigit() 
    if x_int and y_int: 
     x, y = map(int, (x, y)) 
    if (x_int and y_int) or (not x_int and not y_int): 
     return cmp(x, y) 
    elif x_int: 
     # digits must come before non-digits 
     return -1 
    else: 
     # non-digits must come after digits 
     return 1 

lines = sorted((line for line in infile if line.strip()), cmp=mycmp) 
+0

文件是一个.txt文件,每个文件中有3个条目行由制表符分隔。我想根据每行中的第一个条目对它进行排序。但是,它们并不全是int。第一列中还有2个字符X和Y.所以int(x)可能不起作用。 –

+0

@BaturayKaya:参考更新的代码片段 - 你只需要检查第一个“列”是否可以转换为int - 但请注意警告。 –

+0

增加了一个更强大的解决方案 –

0

它将值解释为字符串,所以19确实是“小于”2。您可以将它们转换为int以通过数字值对它们进行正确排序。

lines=[map(int,line) for line in inputFile if line.strip()] 
lines.sort() 

或者,如果你不想修改值,并想离开他们作为字符串:

lines.sort(key=lambda i : int(i)) 
+0

我试过这个,但它给“int()与基数10无效的字面值:'' –

+0

你有只有像”1“,”2“的值,或者你有像”1.5“,3.2”等小数? – CoryKramer

+0

我有整数1,2,3和两个字符的X和Y.我想要的结果是:1 2 3 4 5 ...... XY –

0

人们还可以使用该密钥参数排序功能:

def get_key(a): 
    return [int(x) if x.isdigit() else x for x in a.split('\t')] 

lines = sorted((line for line in infile if line.strip()), key=get_key) 

编辑:要解决的实现细节在字符串之前对整数进行排序,可以使用以下按键功能(但这会导致字符保持未排序状态):

def get_key(a): 
    return [int(x) if x.isdigit() else float('inf') for x in a.split('\t')] 

lines = sorted((line for line in infile if line.strip()), key=get_key) 
+0

请参考我自己的答案中的警告:这依赖于在字符串之前实现排序。 –

+0

我想,我添加了一个修改来解决这个问题。 –

相关问题