user2333133
user2333133

Reputation: 27

Python sort text file in dictionary

I have a text file that looks something like this:

John Graham 2
Marcus Bishop 0
Bob Hamilton 1
... and like 20 other names.

Each name appears several times and with a different number(score) after it. I need to make a list that shows each name only one time and with a sum of that name's total score efter it. I need to use a dictionary.

This is what i have done, but it only makes a list like the text file looked like from the beginning:

dict = {}

with open('scores.txt', 'r+') as f:
    data = f.readlines()


    for line in data:
        nameScore = line.split()
        print (nameScore)

I don't know how to do the next part.

Upvotes: 0

Views: 2243

Answers (4)

Johnny Stinson
Johnny Stinson

Reputation: 21

I had a similar situation I was in. I modified Wesley's Code to work for my specific situation. I had a mapping file "sort.txt" that consisted of different .pdf files and numbers to indicate the order that I want them in based on an output from DOM manipulation from a website. I wanted to combine all these separate pdf files into a single pdf file but I wanted to retain the same order they are in as they are on the website. So I wanted to append numbers according to their tree location in a navigation menu.

1054 spellchecking.pdf
1055 using-macros-in-the-editor.pdf
1056 binding-macros-with-keyboard-shortcuts.pdf
1057 editing-macros.pdf
1058 etc........

Here is the Code I came up with:

import os, sys

# A dict with keys being the old filenames and values being the new filenames
mapping = {}

# Read through the mapping file line-by-line and populate 'mapping'
with open('sort.txt') as mapping_file:
    for line in mapping_file:

        # Split the line along whitespace
        # Note: this fails if your filenames have whitespace
        new_name, old_name = line.split()
        mapping[old_name] = new_name


# List the files in the current directory
for filename in os.listdir('.'):
    root, extension = os.path.splitext(filename)

    #rename, put number first to allow for sorting by name and 
    #then append original filename +e extension
    if filename in mapping:
        print "yay" #to make coding fun
        os.rename(filename, mapping[filename] + filename + extension)

I didn't have a suffix like _full so I didn't need that code. Other than that its the same code, I've never really touched python so this was a good learning experience for me.

Upvotes: 0

Kirk Strauser
Kirk Strauser

Reputation: 30947

My first pass would look like:

scores = {}  # Not `dict`. Don't reuse builtin names.

with open('scores.txt', 'r') as f:  # Not "r+" unless you want to write later
    for line in f:
        name, score = line.strip().rsplit(' ', 1)
        score = int(score)
        if name in scores:
            scores[name] = scores[name] + score
        else:
            scores[name] = score

print scores.items()

This isn't exactly how I'd write it, but I wanted to be explicit enough that you could follow along.

Upvotes: 1

alecxe
alecxe

Reputation: 474031

Here is one option using defaultdict(int):

from collections import defaultdict

result = defaultdict(int)
with open('scores.txt', 'r') as f:
    for line in f:
        key, value = line.rsplit(' ', 1)
        result[key] += int(value.strip())

print result

If the contents of scores.txt is:

John Graham 2
Marcus Bishop 0
Bob Hamilton 1
John Graham 3
Marcus Bishop 10

it prints:

defaultdict(<type 'int'>, 
            {'Bob Hamilton': 1, 'John Graham': 5, 'Marcus Bishop': 10})

UPD (formatting output):

for key, value in result.iteritems():
    print key, value

Upvotes: 5

venpa
venpa

Reputation: 4318

use dictionary get:

dict = {}
with open('file.txt', 'r+') as f:
    data = f.readlines()
    for line in data:
        nameScore = line.split()
        l=len(nameScore)
        n=" ".join(nameScore[:l-1])
        dict[n] = dict.get(n,0) + int(nameScore[-1])

print dict

Output:

{'Bob Hamilton': 1, 'John Graham': 2, 'Marcus Bishop': 0}

Upvotes: 0

Related Questions