Search code examples
pythonlistindexinglist-comprehension

Replace the ',' (comma) with a ' ' (space) after every nth element of a list and write it to a text file in python


I have the following question. bbox2 is a list of data points, and as you see every bbox2[k - 1::k] element is 0.

save_text = [image_path]
bbox2 = [126,0,178,38,0,254,415,316,472,0,390,292,423,326,0]
bbox2 = str(bbox2).replace(' ', '')
save_text.append(bbox2)
with open('output.txt', 'a') as file:
               file.write(' '.join(map(str, save_text)).replace('[', '').replace(']', '') + '\n')

Now please look at the output. The output I am getting is:

output:
DSC07368_053.jpg 126,0,178,38,0,254,415,316,472,0,390,292,423,326,0

So now my question is how can I write this text file like the expected output.

Expected output:
DSC07368_053.jpg 126,0,178,38,0 254,415,316,472,0 390,292,423,326,0

If I use another .replace(',0,',',0 ') then there is a problem because it is replacing all of it but I need the space after each bbox2[k - 1::k] element instead of a comma.


Solution

  • You could use while-loop with bbox2[:k] and bbox2[k:] to convert list to 2D list

    bbox2 = [126,0,178,38,0,254,415,316,472,0,390,292,423,326,0]
    
    k = 5
    
    list2D = []
    
    while bbox2:
        list2D.append(bbox2[:k])  # beginnig elements
        bbox2 = bbox2[k:]         # rest of list
    
    print(list2D)
    

    Result:

    [ 
       [126, 0, 178, 38, 0], 
       [254, 415, 316, 472, 0], 
       [390, 292, 423, 326, 0]
    ]
    

    And this list is simply to convert to list of strings

    substrings = ["DSC07368_053.jpg"]
    
    for sublist in list2D:
        text = ",".join( map(str, sublist) )
        substrings.append(text)
        
    print(substrings)   
    

    Result:

    [ "DSC07368_053.jpg", "126,0,178,38,0",  "254,415,316,472,0", "390,292,423,326,0" ]
    

    And now you need only " ".join() to convert to single string

    result = " ".join(substrings)
    

    Result:

    DSC07368_053.jpg 126,0,178,38,0 254,415,316,472,0 390,292,423,326,0
    

    Full code can be reduced to

    bbox2 = [126,0,178,38,0,254,415,316,472,0,390,292,423,326,0]
    
    k = 5
    
    substrings = ["DSC07368_053.jpg"]
    
    while bbox2:
        sublist = bbox2[:k]  # beginnig elements
        bbox2 = bbox2[k:]    # rest of list
    
        text = ",".join( map(str, sublist) )
        substrings.append(text)
        
    result = " ".join(substrings)
    
    print(result)
    

    But version with while-loop destroys original bbox2 and to keep original bbox2 you would have to duplicate it with bbox2.copy().

    Or it is situation when range(len()) can be useful.

    bbox2 = [126,0,178,38,0,254,415,316,472,0,390,292,423,326,0]
    
    k = 5
    
    substrings = ["DSC07368_053.jpg"]
    
    for x in range(0, len(bbox2), k):
        sublist = bbox2[x:x+k]
        text = ",".join(map(str, sublist))
        substrings.append(text)
        
    result = " ".join(substrings)
    
    print(result)
    

    It can be use to create useful function slicer()

    def slicer(data, k):
        for x in range(0, len(data), k):
            yield data[x:x+k]
        
    # ---
    
    bbox2 = [126,0,178,38,0,254,415,316,472,0,390,292,423,326,0]
    
    k = 5
    
    substrings = ["DSC07368_053.jpg"]
    
    for sublist in slicer(bbox2, k):
        text = ",".join(map(str, sublist))
        substrings.append(text)
        
    result = " ".join(substrings)
    
    print(result)