用Python根据第一列排序文本文件

0 投票
3 回答
2324 浏览
提问于 2025-04-18 13:44

我刚开始学习Python。我有一个文本文件,里面有三列数据,第一列是数字。我想把这个文本文件的行按数字从小到大排序。我试过这样做:

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

但是,文件的排序结果不是按数字排序,而是按字母顺序排序的。例如,排序结果是1, 11, 12, 13, 14,...19, 2, 21,... 我该怎么解决这个问题呢?

谢谢。

3 个回答

-1

你也可以在排序函数中使用一个叫做“key”的参数:

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)

编辑:为了绕过一个实现细节,即整数会在字符串之前排序,你可以使用下面这个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

它把这些值当成字符串来处理,所以实际上 19 是“比” 2 小的。你可以把它们转换成 int 类型,这样就能按照数字的大小来正确排序。

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

或者,如果你不想修改这些值,想把它们保持为字符串:

lines.sort(key=lambda i : int(i))
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())

注意:这个方法依赖于CPython 2.7的一个实现细节,可能在其他版本的Python中无法正常工作(据我所知,在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)

撰写回答