Danny Bradshaw
Danny Bradshaw

Reputation: 13

python split and reverse text file

I have a text file which stores data like name : score e.g.:

bob : 10
fred : 3
george : 5

However, I want to make it so it says

10 : bob
3 : fred
5 : george

What would the code be to flip it like that? Would I need to separate them first by removing the colon as I have managed this through this code?

file = open("Class 3.txt", "r")
t4 = (file.read())
test =''.join(t4.split(':')[0:10])
print (test)

How would I finish it and make it say the reverse?

Upvotes: 1

Views: 848

Answers (3)

Hai Vu
Hai Vu

Reputation: 40763

Let's learn how to reverse a single line:

line = `bob : 10`
line.partition(' : ')  # ('10', ' : ', 'bob')
''.join(reversed(line.partition(' : '))  # 'bob : 10'

Now, combine with reading lines from a file:

for line in open('Class 3.txt').read().splitlines():
    print ''.join(reversed(line.partition(' : '))

Update

I am re-writing the code to read the file, line by line:

with open('Class 3.txt') as input_file:
    for line in input_file:
        line = line.strip()
        print ''.join(reversed(line.partition(' : ')))

Upvotes: 0

TigerhawkT3
TigerhawkT3

Reputation: 49330

This code handles fractional scores (e.g. 9.5), and doesn't care whether there are extra spaces around the : delimiter. It should be much easier to maintain than your current code.

Class 3.txt:

bob : 10
fred : 3
george : 5

Code:

class_num = input('Which class (1, 2, or 3)? ')
score_sort = input('Sort by name or score? ').lower().startswith('s')

with open("Class " + class_num + ".txt", "r") as f:
    scores = {name.strip():float(score) for
              name,score in (line.strip().split(':') for line in f)}
    if score_sort:
        for name in sorted(scores, key=scores.get, reverse=True):
            print(scores.get(name), ':', name)
    else:
        for name in sorted(scores):
            print(name, ':', scores.get(name))

Input:

3
scores

Output:

10.0 : bob
5.0 : george
3.0 : fred

Input:

3
name

Output:

bob : 10.0
fred : 3.0
george : 5.0

Upvotes: 1

abarnert
abarnert

Reputation: 365925

First, this is going to be a lot harder to do whole-file-at-once than line-at-a-time.

But, either way, you obviously can't just split(':') and then ''.join(…). All that's going to do is replace colons with nothing. You obviously need ':'.join(…) to put the colons back in.

And meanwhile, you have to swap the values around on each side of each colon.

So, here's a function that takes just one line, and swaps the sides:

def swap_sides(line):
    left, right = line.split(':')
    return ':'.join((right, left))

But you'll notice there's a few problems here. The left has a space before the colon; the right has a space after the colon, and a newline at the end. How are you going to deal with that?

The simplest way is to just strip out all the whitespace on both sides, then add back in the whitespace you want:

def swap_sides(line):
    left, right = line.split(':')
    return ':'.join((right.strip() + ' ', ' ' + left.strip())) + '\n'

But a smarter idea is to treat the space around the colon as part of the delimiter. (The newline, you'll still need to handle manually.)

def swap_sides(line):
    left, right = line.strip().split(' : ')
    return ' : '.join((right.strip(), left.strip())) + '\n'

But if you think about it, do you really need to add the newline back on? If you're just going to pass it to print, the answer is obviously no. So:

def swap_sides(line):
    left, right = line.strip().split(' : ')
    return ' : '.join((right.strip(), left.strip()))

Anyway, once you're happy with this function, you just write a loop that calls it once for each line. For example:

with open("Class 3.txt", "r") as file:
    for line in file:
        swapped_line = swap_sides(line)
        print(swapped_line)

Upvotes: 0

Related Questions