-2

How do I sort a text file by three columns with a specific order to those columns in Python?

My text_file is in the following format with whitespaces between columns:

Team_Name Team_Mascot Team_Color Team_Hometown Number_of_Wins Team_Coach

Example:

Bears LittleBear Blue Beartown 15 BigBear

I want to sort it by Team_Color first, Team_Hometown second, and Number_of_Wins third in ascending order.

Therefore the attributes:

Bears Blue Beartown 15 Coach1
Bears Red  Dogtown 30 Coach6
Bears Blue Cattown 15 Coach2
Bears Red  Beartown 15 Coach4
Bears Blue Cattown 17 Coach3
Bears Red  Dogtown 9 Coach5

My expected output is a sorted text file:

Bears Blue Beartown 15 Coach1
Bears Blue Cattown 15 Coach2
Bears Blue Cattown 17 Coach3
Bears Red  Beartown 15 Coach4
Bears Red  Dogtown 9 Coach5
Bears Red  Dogtown 30 Coach6

I have thought about using lambda but none of my values are a tuple https://docs.python.org/3/tutorial/controlflow.html

I have looked at previous StackOverflow questions but most of them dealt with sorting two columns at maximum using lambda, tuple, or other methods

  • @Piinthesky You're right. I should have not used a dictionary and instead focused on editing the text file directly –  Feb 10 '18 at 23:43
  • @idjaw I clarified why my question is not a duplicate –  Feb 10 '18 at 23:43
  • How are the entries separated in your text file? Tabs? Double whitespace? And what is your expected output? Another text file? – Mr. T Feb 10 '18 at 23:47
  • 1
    Your question is unclear. Is the data now in text format, so you need to read it first, then sort, then save back to the text file, or is the data already in memory for your question? Your example with the attributes is missing either the team name or the team mascot. Could you give a full, complete example input, with the desired full, complete, desired output? Read and follow [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Finally, could you show us some of your attempted code? Just saying "you thought" about something is not enough. – Rory Daulton Feb 10 '18 at 23:56
  • @Piinthesky My entries are separated by whitespave characters and my expected output is a sorted text file: –  Feb 10 '18 at 23:56
  • @Roadrunner Tried making into a dictionary using sorted(dictionary, lambda x: (x[3], x[4]) and then nestong sorted dictionaries. That didn’t work –  Feb 11 '18 at 00:00
  • What happens, if the home town is "New York"? How is the program supposed to know, that they are one entry and not two? – Mr. T Feb 11 '18 at 00:02
  • @Piinthesky In this scenario, all of the home towns are single words like “Boston” or “London” only –  Feb 11 '18 at 00:04

2 Answers2

1

Your question is still ambiguous. Your example doesn't have the first field Team_Name introduced in your header. So the index here is probably off by one, but I think you get the concept:

#read lines of text file and split into words
lines = [line.split() for line in open("test.txt", "r")]
#sort lines for different columns, numbers converted into integers to prevent lexicographical sorting
lines.sort(key = lambda x: (x[1], x[2], int(x[3])))
#writing the sorted list into another file
with open("new_test.txt", "w") as f:
    for item in lines:
        f.write(" ".join(item) + "\n")
Mr. T
  • 11,960
  • 10
  • 32
  • 54
  • This worked. Thanks for the help. I should have been more clear in my question and I'll be sure to do so in the future. –  Feb 11 '18 at 01:07
1

You can do it using itemgetter from the operator module:

from operator import itemgetter

def showList(inList):
    for i in inList:
        print(i)

lines = []

with open("test.txt", "r") as infile:
    lines = [i.split() for i in infile.readlines()]
    lines = [[int(j) if j.isdigit() else j for j in i] for i in lines]
    showList(lines)
    lines = sorted(lines, key=itemgetter(1,2,3))
    print()
    showList(lines)

with open("output.txt", "w") as outfile:
    for line in lines:
        outfile.write(" ".join(str(i) for i in line) + "\n")

Output (using showList):

['Bears', 'Blue', 'Beartown', 15, 'Coach1']
['Bears', 'Red', 'Dogtown', 30, 'Coach6']
['Bears', 'Blue', 'Cattown', 15, 'Coach2']
['Bears', 'Red', 'Beartown', 15, 'Coach4']
['Bears', 'Blue', 'Cattown', 17, 'Coach3']
['Bears', 'Red', 'Dogtown', 9, 'Coach5']

['Bears', 'Blue', 'Beartown', 15, 'Coach1']
['Bears', 'Blue', 'Cattown', 15, 'Coach2']
['Bears', 'Blue', 'Cattown', 17, 'Coach3']
['Bears', 'Red', 'Beartown', 15, 'Coach4']
['Bears', 'Red', 'Dogtown', 9, 'Coach5']
['Bears', 'Red', 'Dogtown', 30, 'Coach6']

Output format in new file:

Bears Blue Beartown 15 Coach1
Bears Blue Cattown 15 Coach2
Bears Blue Cattown 17 Coach3
Bears Red Beartown 15 Coach4
Bears Red Dogtown 9 Coach5
Bears Red Dogtown 30 Coach6
Vasilis G.
  • 7,556
  • 4
  • 19
  • 29