Как отсортировать ввод без организации поля фиксированной ширины? - PullRequest
1 голос
/ 29 июня 2019

У меня есть файл .txt, полный таких строк, как:

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

, где Score - целое число от 0 до 1 млрд.

И я хочу отсортировать этот файл по баллам от большого к маленькому. Моя проблема в том, что, поскольку имена и электронные письма имеют разную длину, оценка не всегда одинакова, когда я могу получить к ней доступ. Как бы я преодолел эту проблему?

(Я не очень уверен, как правильно произнести название, поэтому надеюсь, что это тело сможет объяснить его лучше; пожалуйста, дайте мне знать, если вопрос не ясен)

Ответы [ 5 ]

0 голосов
/ 29 июня 2019

Ваши входные данные - 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
0 голосов
/ 29 июня 2019

Использовать пользовательскую функцию сортировки клавиш для 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']
0 голосов
/ 29 июня 2019

Во-первых, мы можем прочитать строки файла.Далее мы используем понимание списка, чтобы разделить каждую строку в разделителе «|», взять последний индекс и преобразовать в целое число для сортировки.Мы сортируем в обратном порядке и устанавливаем ключ так, чтобы на выходе были индексы строк, а затем устанавливаем 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]

См. этот вопрос длядополнительные предложения по сортировке и возврату индекса.

Пример С файлом "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"]
0 голосов
/ 29 июня 2019

Если у вас есть строки в списке, вы можете использовать sort или sorted для их сортировки.Трюк будет передавать ключ, который вытаскивает это целое число.Один из вариантов - взять фрагмент из последней | до конца строки и сделать целое число из этой строки.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']
0 голосов
/ 29 июня 2019

#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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...