0

Okay, before I ask, I have already seen the following answers:

Python OrderedDict not keeping element order

Converting dict to OrderedDict

OrderedDict does not preserve the order

but still I am unable to make it right.

Background: I have a groundtruth file, like, jp1_GT.txt (there are other files too, at different paths but currently I am concerned with just one file) at some path. In this file, each line represents one bounding box in the format . I am changing the with some calculation, and aim to write them in a new groundtruth file.

#Path containing old folders
src_path = r"C:\Users\username\Downloads\LITIV_dataset"

#dictionary creation
newgtdict ={}

for folderName in os.listdir(src_path):
  folderPath = src_path + "\\" + folderName

  if not os.path.isdir(folderPath):
    continue

  listOfFilePaths = glob.glob(folderPath + "\\"+ folderName +"_GT.txt")
  for filePath in listOfFilePaths:

    openedFile = open(filePath, 'r')
    lines = openedFile.readlines()
    linecount =0

    for line in lines:
        linecount+=1
        linenumber = str(linecount)
        my_list = str(line).split(",")
        bboxes=[]

        #checking for non-empty lines
        if len(my_list)>0:
            x_br = int(my_list[2])
            y_br = int(my_list[3])
            x_tl = int(my_list[0]) - (x_br/2)
            y_tl = int(my_list[1]) - (y_br/2)
            box = [x_tl,y_tl,x_br,y_br]
        newgtdict[str(filePath)+str(linenumber)] = box 
        print newgtdict

The first four lines of my jp1_GT.txt looks like this:

189,163,72,72
190,162,72,72
188,160,72,72
189,163,72,72

However, first four lines of output looks like this:

{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt1': [153, 127, 72, 72]} 
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt1': [153, 127, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt2': [154, 126, 72, 72]} 
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt1': [153, 127, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt3': [152, 124, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt2': [154, 126, 72, 72]}
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt4': [153, 127, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt1': [153, 127, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt3': [152, 124, 72, 72], 'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt2': [154, 126, 72, 72]}

Expected first 4 lines of output:

{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt1': [153, 127, 72, 72]} 
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt2': [154, 126, 72, 72]} 
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt3': [152, 124, 72, 72]} 
{'C:\\Users\\username\\Downloads\\LITIV_dataset\\jp1\\jp1_GT.txt4': [153, 127, 72, 72]} 

Just a side question: Do you suggest any other better way to this.

Sulphur
  • 514
  • 6
  • 24
  • Dictionary items do not have a defined order. If you want to preserve order you need to use an OrderedDict. – jbch May 09 '18 at 22:04
  • @jbch actually not true in modern Python, but that doesn't appear to be the issue here anyway. – Adam Smith May 09 '18 at 22:05
  • True, dicts keep their orders as of 3.7. – jbch May 09 '18 at 22:06
  • @jbch thanks for the sanity check there -- I forgot which version that went live in. I thought it was 3.6 -- now I see it was only an implementation detail in CPython 3.6 – Adam Smith May 09 '18 at 22:37

1 Answers1

3

You're printing the dictionary on each iteration, rather than the new item to the dictionary on each iteration.

You could either do:

for line in lines:
    # <snip>
    newgtdict[str(filePath)+str(linenumber)] = box 
    print box

or

for line in lines:
    # <snip>
    newgtdict[str(filePath)+str(linenumber)] = box 
    # don't print here

for line in newgtdict:
    print(line)

Do note that you're not using an OrderedDict, which you should (if you want ordered results in versions of Python earlier than 3.7)

newgtdict = collections.OrderedDict()
# rather than = {}
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • If their expected output is correct it looks like they want a new dict for each line, not to print each line. – jbch May 09 '18 at 22:08
  • @jbch that's true, but I can't imagine a legitimate use for that expected output, so I'm taking poetic license that it's a mistake – Adam Smith May 09 '18 at 22:09
  • That's probably fair. It would be quite a strange use case. – jbch May 09 '18 at 22:10
  • @jbch I may be going wrong but just thought to clarify. I wanted to write the modified contents of this file (every line) in a newly created file. And hence was using the dictionary method. So I will make a dictionary for the entire file or each line? P.S. haven't used dictionary much. Sorry. – Sulphur May 09 '18 at 22:14
  • @AdamSmithI wanted to add you to my above question but I couldn't hence mention in the new comment. – Sulphur May 09 '18 at 22:16
  • @AdamSmith I modified the code and also added: `newgtdict = collections.OrderedDict()`. However,I get an error `name 'collections' is not defined` though I have done `from collections import OrderedDict` – Sulphur May 09 '18 at 22:20
  • @Sulphur unless you need the information in memory somehow, I wouldn't bother collating the info as a dictionary. I'd write straight across [like so](https://repl.it/repls/CrookedInterestingEvaluations) – Adam Smith May 09 '18 at 22:25
  • 1
    @Sulphur if you've done `from collections import OrderedDict`, then just declare as `newgtdict = OrderedDict`. You only need the fully-qualified name if you've written `import collections`. – Adam Smith May 09 '18 at 22:26