0

Problem.txt file:

Class    Confidence     Xmin       Ymin     Xmax      Ymax
6        0.9917297      62         0        81        76
1        0.99119675     0          41       8         83
9        0.8642462      23         31       46        98
4        0.8287333      22         30       45        95

My expected output is:

1        0.99119675     0          41       8         83
4        0.8287333      22         30       45        95
9        0.8642462      23         31       46        98
6        0.9917297      62         0        81        76

My code is given bellow:

from collections import defaultdict
import os

for root, dirs, files in os.walk(r'F:\GGR\process'):  # this recurses into subdirectories as well
    for f in files:
        maxima = defaultdict(int)
        try:
            with open(os.path.join(root,f)) as ifh:
                for line in ifh:
                    key, value = line.rsplit(None, 1)
                    value = int(value)
                    if value > maxima[key]:
                        maxima[key] = value

            with open(os.path.join(root, f'{f}.out'), 'w') as ofh:
                for key in sorted(maxima):
                    ofh.write('{} {}\n'.format(key, maxima[key]))
        except ValueError:
            # if you have other files in your dir, you might get this error because they
            # do not conform to the structure of your "needed" files - skip those
            print(f, "Error converting value to int:", value)

After run this script, Output will show:

1 0.99119675  0  41  8   83
4 0.8287333  22  30  45  95
6 0.9917297  62  0   81   76
9 0.8642462  23  31  46  98

I can't understand what is the wrong in my code. Please fix this problem anf how can i get expected output for this program ?

offline
  • 69
  • 1
  • 11
  • Your error is the use of `defaultdict`, you should be using `OrderedDict`. The order of data stored in / printed from a dictionary is unpredictable due to how the hashes of the keys are calculated and stored. OrderedDict will provide dictionary-like functionality while maintaining the order in which the elements were added to it. – jrd1 Aug 05 '19 at 05:10
  • dictionaries in python >=3.6 keep their insertion order: https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6 – hiro protagonist Aug 05 '19 at 05:11
  • @hiroprotagonist: Agreed, however the OP doesn't state which version of Python 3 is being used – jrd1 Aug 05 '19 at 05:14
  • When used orderDict that you mentioned then error prompt will show like: NameError: name 'OrderedDict' is not defined – offline Aug 05 '19 at 05:21
  • `OrderedDict` has to be imported from collections. However, looking more carefully at your code, I believe the error is also related to the use of `sorted`. You're likely reading your file properly, however, this line `for key in sorted(maxima)` sorts the keys being used to print. If you notice the key / value pairs, the keys are sorted. Remove `sorted`, and use `OrderedDict` (if Python3 < 3.6) and it _should_ work as intended. – jrd1 Aug 05 '19 at 05:24
  • Already import OrderDict and used this in my code but i can't understand actually because i'm not familiar with Python file. Please fix this error!! – offline Aug 05 '19 at 05:28

1 Answers1

0

You're getting the output stated due to this line:

for key in sorted(maxima):

This means that if your keys were 6, 1, 9, 4 they would become 1, 4, 6, 9, which is exactly the order they're displayed in the output you showed. What you want is for the dictionary to be read and output in the order it was added. If you're using Python3.6 and greater, remove the sorted and the output will be printed in the order that the data was added.

If you're using an earlier version of Python3, you'll need a container that can keep track of the order in which the keys and values were added, in addition to the removal of sorted. That is make maxima an OrderedDict (this is from the collections package), and convert the for loop that prints the keys to for key in maxima.

jrd1
  • 10,358
  • 4
  • 34
  • 51