没有固定宽度的字段组织如何对输入进行排序?

时间:2019-06-29 01:25:37

标签: python csv file-io

我有一个.txt文件,其中包含以下几行:

Name | Email@example.com | Score
Name2 | Email2@madeupsite.com | Score 

其中Score是0到10亿之间的整数。

我想按分数从大到小对这个文件进行排序。我的问题是,由于姓名和电子邮件的长度不同,所以每次访问分数时,分数就不会一致。我将如何克服这个问题?

(我不太确定标题的措词,所以我希望这个机构可以更好地解释它;如果问题不清楚,请让我知道)

5 个答案:

答案 0 :(得分:0)


#a list to store your data, open the file to retrieve the data
data = []
with open( 'fname.txt' ) as f:
    for line in f:
        # line.split( '|' ) splits the string into a list separated by '|' )
        data.append( line.strip().split('|') )

# convert the scores into an integer
for d in data:
    d[2] = int( d[2] )

# sort the data using 2nd element of row from big to small
sorted_data = sorted( data, key=lambda x: return x[2], reverse=True )

答案 1 :(得分:0)

首先,我们可以读取文件的各行。接下来,我们使用列表推导对分隔符“ |”上的每一行进行拆分,获取最后一个索引,然后转换为整数进行排序。我们以相反的顺序排序并设置键,以便输出为行索引,然后将lines_sorted设置为与排序的行的顺序相等。

with open("file.txt", "r") as f:
    lines = f.readlines()
    scores = [int(l.split("|")[-1]) for l in lines]
    sorted_idx = sorted(range(len(scores)), key=lambda k: scores[k], reverse=True)
    lines_sorted = [lines[i] for i in sorted_idx]

有关this question排序和返回索引的更多建议。

示例 使用包含以下内容的“ file.txt”:

Name | Email@example.com | 1000
Name2 | Email2@madeupsite.com | 10
Name3 | Email3@madeupsite.com | 100

lines_sorted将包含:

["Name | Email@example.com | 1000",
 "Name3 | Email3@madeupsite.com | 100", 
 "Name2 | Email2@madeupsite.com | 10"]

答案 2 :(得分:0)

列表中有行之后,就可以使用sortsorted对其进行排序。诀窍将是传递一个提取该整数的键。一种选择是从最后一个|到行尾截取一个切片,然后从该字符串中得到一个整数。 rfind()为此:

lines = ['Name | Email@example.com | 1001',
         'Name2 | Email2@madeupsite.com | 2',
         'Name2 | Email2@madeupsite.com | 200'
]

s = sorted(lines, key = lambda s: int(s[s.rfind('|')+1:]))
list(s)

结果:

['Name2 | Email2@madeupsite.com | 2',
 'Name2 | Email2@madeupsite.com | 200',
 'Name | Email@example.com | 1001']

答案 3 :(得分:0)

在每个字符串的rpartition上使用自定义排序键功能

输入:

lines = ['Name | Email@example.com | 50',
         'Name2 | Email2@madeupsite.com | 400',
         'Name3 | Email2@madeupsite.com | 15']

输出:

sorted(lines, key=lambda x: int(x.rpartition('|')[-1]))

Out[1128]:
['Name3 | Email2@madeupsite.com | 15',
 'Name | Email@example.com | 50',
 'Name2 | Email2@madeupsite.com | 400']

答案 4 :(得分:0)

您的输入数据是PSV(管道分离值)。您可以使用pandas.read_csv with sep='|'来阅读它:

dat = """
Name1 | Email@example.com | 456
Name2 | Email2@madeupsite.com | 123 
Name44 | jimmy@yahoo.co.ar | 79
"""

import pandas as pd
df = pd.read_csv(pd.compat.StringIO(dat), sep='|', header=None)

df.sort_values(2, ascending=True)

         0                        1    2
2  Name44        jimmy@yahoo.co.ar    79
1   Name2    Email2@madeupsite.com   123
0   Name1        Email@example.com   456
相关问题