Newbie
Newbie

Reputation: 376

Python Sorting Contents of txt file

I have a function that opens a file called: "table1.txt" and outputs the comma separated values into a certain format.

My function is:

def sort_and_format():

    contents = []
    with open('table1.txt', 'r+') as f:
        for line in f:
            contents.append(line.split(','))

    max_name_length = max([len(line[0]) for line in contents])

    print("     Team                       Points  Diff  Goals     \n")
    print("--------------------------------------------------------------------------\n")
    for i, line in enumerate(contents):
        line = [el.replace('\n', '') for el in line]
        print("{i:3}  {0:{fill_width}}   {1:3}   {x:3}   {2:3} :{3:3}".format(i=i+1, *line,
        x = (int(line[2])- int(line[3])), fill_width=max_name_length))

I figured out how to format it correctly so for a "table1.txt file of:

FC Ingolstadt 04, 13, 4, 6
Hamburg, 9, 8, 10
SV Darmstadt 98, 9, 8, 9
Mainz, 9, 6, 9
FC Augsburg, 4, 7, 12
Werder Bremen, 6, 7, 12
Borussia Moenchengladbach, 6, 9, 15
Hoffenheim, 5, 8, 12
VfB Stuttgart, 4, 9, 17
Schalke 04, 16, 14, 3 
Hannover 96, 2, 6, 18
Borrusia Dortmund, 16, 15, 4 
Bayern Munich, 18, 18, 2
Bayer Leverkusen, 14, 11, 8
Eintracht Frankfurt, 9, 13, 9
Hertha BSC Berlin, 14, 5, 4
1. FC Cologne, 13, 10, 10
VfB Wolfsburg, 14, 10, 6

It would output:

Team                             Points  Diff  Goals     

--------------------------------------------------------------------------

  1  FC Ingolstadt 04             13    -2    4  : 6 
  2  Hamburg                      9     -2    8  : 10
  3  SV Darmstadt 98              9     -1    8  : 9 
  4  Mainz                        9     -3    6  : 9 
  5  FC Augsburg                  4     -5    7  : 12
  6  Werder Bremen                6     -5    7  : 12
  7  Borussia Moenchengladbach    6     -6    9  : 15
  8  Hoffenheim                   5     -4    8  : 12
  9  VfB Stuttgart                4     -8    9  : 17
 10  Schalke 04                   16    11    14 : 3 
 11  Hannover 96                  2    -12    6  : 18
 12  Borrusia Dortmund            16    11    15 : 4 
 13  Bayern Munich                18    16    18 : 2 
 14  Bayer Leverkusen             14     3    11 : 8 
 15  Eintracht Frankfurt          9      4    13 : 9 
 16  Hertha BSC Berlin            14     1    5  : 4 
 17  1. FC Cologne                13     0    10 : 10
 18  VfB Wolfsburg                14     4    10 : 6 

I am trying to figure out how to sort the file so that the team with the highest points would be ranked number 1, and if a team has equal points then they are ranked by diff(the difference in goals for and against the team), and if the diff is the same they are ranked by goals scored.

I thought of implementing a bubble sort function similar to:

def bubble_sort(lst):
    j = len(lst)
    made_swap = True
    swaps = 0
    while made_swap:
        made_swap = False
        for cnt in range (j-1):
            if lst[cnt] < lst[cnt+1]:
                lst[cnt], lst[cnt+1] = lst[cnt+1], lst[cnt]
                made_swap = True
                swaps = swaps + 1
    return swaps

But I do not know how to isolate each line and compare the values of each to one another to sort.

Upvotes: 5

Views: 680

Answers (3)

LetzerWille
LetzerWille

Reputation: 5658

I have joined spaces in the first column with _ to make life easier, so the data looks like:

    F_ngolstad_4             13    -2      4:6
    Hamburg                      9    -2  8:10
    S_armstad_8              9     -1      8:9
    Mainz                        9   -3    6:9
    F_ugsburg                  4     -5    7:12
    Werde_remen                6     -5    7:12
    Borussi_oenchengladbach    6     -6    9:15
    Hoffenheim                   5   -4    8:12
    Vf_tuttgart                4     -8    9:17
    Schalk_4                   16    11    14:3
    Hannove_6                  2    -12    6:18
    Borrusi_ortmund            16    11    15:4
    Bayer_munich                18    16    18:2
    Baye_everkusen             14     3    11:8
    Eintrach_rankfurt          9      4    13:9
    Herth_S_erlin            14     1      5:4
    1._F_ologne                13     0    10:10
    Vf_olfsburg                14     4    10:6

all_lines = []
with open('data', 'r') as f:
    for line in f:
        li = line.split()
        all_lines.append(li)


l = sorted(all_lines,key=lambda x: (int(x[1]),int(x[2])),reverse=True)
for el in l:
    print(el)

['Bayer_munich', '18', '16', '18:2']
['Schalk_4', '16', '11', '14:3']
['Borrusi_ortmund', '16', '11', '15:4']
['Vf_olfsburg', '14', '4', '10:6']
['Baye_everkusen', '14', '3', '11:8']
['Herth_S_erlin', '14', '1', '5:4']
['1._F_ologne', '13', '0', '10:10']
['F_ngolstad_4', '13', '-2', '4:6']
['Eintrach_rankfurt', '9', '4', '13:9']
['S_armstad_8', '9', '-1', '8:9']
['Hamburg', '9', '-2', '8:10']
['Mainz', '9', '-3', '6:9']
['Werde_remen', '6', '-5', '7:12']
['Borussi_oenchengladbach', '6', '-6', '9:15']
['Hoffenheim', '5', '-4', '8:12']
['F_ugsburg', '4', '-5', '7:12']
['Vf_tuttgart', '4', '-8', '9:17']
['Hannove_6', '2', '-12', '6:18']

Upvotes: 1

Lgiro
Lgiro

Reputation: 772

contents = [row.strip('\n').split(', ') for row in open('table1.txt', 'r+')]

so that your rows look like:

['FC Ingolstadt 04', '13', '4', '6']

Then you can use Python's built-in sort function:

table = sorted(contents, key=lambda r: (int(r[1]), int(r[2])-int(r[3]), int(r[3])), reverse=True)

and print 'table' with the specific formatting you want.

Upvotes: 2

pppery
pppery

Reputation: 3804

The following code will sort the list in the ways you asked:

from operator import itemgetter
def sort_and_format():
    contents = []
    with open('table1.txt', 'r+') as f:
        for line in f:
            l = line.split(',')
            l[1:]=map(int,l[1:])
            contents.append(l)
    contents.sort(key=itemgetter(2))
    contents.sort(key=lambda team:team[2]-team[3])
    contents.sort(key=itemgetter(1))
    [printing and formatting code]

What this does diferently: First of all, it converts all the data about each team to numbers, excluding the name. This allows the later code to do math on them. Then the first contents.sort statement sorts the list by goals scored (index 2). operator.itemgetter(2) is just a faster way to say lambda l:l[2]. The next contents.sort statement stably sorts the list by goals for minus goals against, as that is what the lambda does. Stable sorting means that the order of equally-compairing elements does not change, so teams with equal goal diff remain sorted by goals scored. The third contents.sort statement does the same stable sort by points.

Upvotes: 2

Related Questions