0

Is there any way to remove duplicate lines in tkinter?

Here's the code:

from tkinter import *

root = Tk()

def remove_duplicate():
    # Code to remove all duplicate lines in the text widget
    pass

text = Text(root , width = 65,  height = 20, font = "consolas 14")
text.pack()

text.insert('1.0' , '''Hello world\n\nHello world\n\nBye bye\n\n\n\n\nBye bye\nBye bye''')

remove_button = Button(root , text = "Remove Duplicate Lines" , command = remove_duplicate)
remove_button.pack()

mainloop()

Here when I click on the remove_button, I want all the duplicate lines in my text widget to be removed.

In this case, I have the string:

"""
Hello world

Hello world

Bye bye




Bye bye
Bye bye
"""

, so when I remove the duplicate lines, I should get something like:

"""
Hello world

Bye bye
"""

Is there any way to achieve this in tkinter?

It would be great if anyone could help me out.

Lenovo 360
  • 569
  • 1
  • 7
  • 27
  • Get the text as a string, manipulate it ([this](https://stackoverflow.com/a/1215244/11106801) might be useful) and then put it back in the `` – TheLizzard Mar 15 '21 at 18:51
  • There are lots of questions on stackoverflow about removing duplicates from lists, and a text widget is in effect a list of strings. Have you done any research about how to remove duplicates from a list of strings? – Bryan Oakley Mar 15 '21 at 19:13
  • @BryanOakley: Yes, I tried everything I can, but no success. – Lenovo 360 Mar 15 '21 at 19:24

1 Answers1

1

The basic idea is to get all the text in the widget, remove the duplicates and add to a new list. Now add the new list items to the text widget, like:

def remove_duplicate():
    val = text.get('0.0','end-1c').split('\n') # Initial values
    dup = [] # Empty list to append all non duplicates
    text.delete('0.0','end-1c') # Remove currently written words
    
    for i in val: # Loop through list
        if i not in dup: # If not duplicate
            dup.append(i) # Append to list
            dup.append('\n') # Add a new line

    text.insert('0.0',''.join(dup)) # Add the new data onto the widget
    text.delete('end-1c','end') # To remove the extra line.

I have explained it with comments to understand-on-the-go. This seems pretty straightforward, though I am sure it can be optimized more.

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46
  • Thanks again for the quick answer @CoolCloud, but I am facing one small issue. When I run this function, there are some unnecessary blank lines at the end. Is there any way to remove those blank lines? – Lenovo 360 Mar 15 '21 at 19:38
  • 1
    @Lenovo360 Try adding `text.delete('end-1c','end')` at the end of func – Delrius Euphoria Mar 15 '21 at 19:44
  • 1
    @Lenovo360 I also removed some more lines, take a look. – Delrius Euphoria Mar 15 '21 at 19:48
  • The first character in a text widget is `"1.0"`, not `"0.0"`. – Bryan Oakley Mar 15 '21 at 20:03
  • @BryanOakley `"1.0"` is the same as `"0.0"` to the tcl interpreter – TheLizzard Mar 15 '21 at 20:04
  • @TheLizzard: yes, but it's a bad practice. Answers should promote best practices whenever possible. – Bryan Oakley Mar 15 '21 at 20:05
  • @BryanOakley I wouldn't say its bad practise. It didn't say it was bad practise when I read the tcl docs [here](https://www.tcl.tk/man/tcl8.4/TkCmd/text.htm#M18). Why do you think its bad practice? – TheLizzard Mar 15 '21 at 20:07
  • I think it's a bad practice because the documentation says the first line is `"1.0"`. That is the documented interface. You can also use `"-3.14159"` but I don't recommend that either. – Bryan Oakley Mar 15 '21 at 20:10
  • @BryanOakley it also says that for *consistency with other UNIX programs* it starts from 0. Also I am so used to list indices that I apply them the `` indices. – TheLizzard Mar 15 '21 at 20:12
  • @TheLizzard: what documentation are you reading? The official tcl/tk docs say _"Lines are numbered from 1 for consistency with other UNIX programs that use this numbering scheme."_. – Bryan Oakley Mar 15 '21 at 20:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229951/discussion-between-thelizzard-and-bryan-oakley). – TheLizzard Mar 15 '21 at 20:15