A better question would have been what are those ("()", "'",",") in the ngrams output?

>>> from nltk import ngrams
>>> from nltk import word_tokenize

# Split a sentence into a list of "words"
>>> word_tokenize("This is a foo bar sentence")
['This', 'is', 'a', 'foo', 'bar', 'sentence']
>>> type(word_tokenize("This is a foo bar sentence"))
<class 'list'>

# Extract bigrams.
>>> list(ngrams(word_tokenize("This is a foo bar sentence"), 2))
[('This', 'is'), ('is', 'a'), ('a', 'foo'), ('foo', 'bar'), ('bar', 'sentence')]

# Okay, so the output is a list, no surprise.
>>> type(list(ngrams(word_tokenize("This is a foo bar sentence"), 2)))
<class 'list'>

But what type is ('This', 'is')?

>>> list(ngrams(word_tokenize("This is a foo bar sentence"), 2))[0]
('This', 'is')
>>> first_thing_in_output = list(ngrams(word_tokenize("This is a foo bar sentence"), 2))[0]
>>> type(first_thing_in_output)
<class 'tuple'>

Ah, it's a tuple, see https://realpython.com/python-lists-tuples/

What happens when you print a tuple?

>>> print(first_thing_in_output)
('This', 'is')

What happens if you convert them into a str()?

>>> print(str(first_thing_in_output))
('This', 'is')

But I want the output This is instead of ('This', 'is'), so I will use the str.join() function, see https://www.geeksforgeeks.org/join-function-python/:

>>> print(' '.join((first_thing_in_output)))
This is

Now this is a good point to really go through the tutorial of basic Python types to understand what is happening. Additionally, it'll be good to understand how "container" types work too, e.g. https://github.com/usaarhat/pywarmups/blob/master/session2.md


Going through the original post, there are quite some issues with the code.

I guess the goal of the code is to:

  • Tokenize the text and remove stopwords
  • Extract ngrams (without stopwords)
  • Print out their string forms and their counts

The tricky part is the stopwords.words('english') does not contain punctuation, so you'll end up with strange ngrams that contains punctuations:

from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english'))

tokens = [token for token in nltk.word_tokenize(text) if token not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('The', 'pure'),
 ('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', ','),
 (',', 'newborn'),
 ('newborn', '.'),
 ('.', 'I'),
 ('I', 'looked'),
 ('looked', 'far'),
 ('far', ','),
 (',', ','), ...]

Perhaps you would like to extend the stoplist with punctuations, e.g.

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('The', 'pure'),
 ('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', 'newborn'),
 ('newborn', 'I'),
 ('I', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'), ...]

Then you realized that tokens like I should be a stopword but still exists in your list of ngrams. It's because the list from stopwords.words('english') are lowercased, e.g.

>>> stopwords.words('english')

[out]:

['i',
 'me',
 'my',
 'myself',
 'we',
 'our',
 'ours',
 'ourselves',
 'you',
 "you're", ...]

So when you're checking whether a token is in the stoplist, you should also lowercase the token. (Avoid lowercasing the sentence before word_tokenize because word_tokenize may take cues from capitalization). Thus:

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token.lower() not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', 'newborn'),
 ('newborn', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'), ...]

Now the ngrams looks like it's achieving the objectives:

  • Tokenize the text and remove stopwords
  • Extract ngrams (without stopwords)

Then on the last part where you want to print out the ngrams to a file in sorted order, you could actually use the Freqdist.most_common() which will list in descending order, e.g.

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords
from nltk import FreqDist

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token.lower() not in stoplist]

FreqDist(ngrams(tokens, 2)).most_common()

[out]:

[(('looked', 'far'), 4),
 (('far', 'looked'), 3),
 (('visual', 'held'), 2),
 (('held', 'memory'), 2),
 (('memory', 'Little'), 2),
 (('Little', 'little'), 2),
 (('little', 'returned'), 2),
 (('returned', 'waking'), 2),
 (('waking', 'nurse'), 2),
 (('pure', 'amnesia'), 1),
 (('amnesia', 'face'), 1),
 (('face', 'newborn'), 1),
 (('newborn', 'looked'), 1),
 (('far', 'visual'), 1),
 (('nurse', 'visual'), 1)]

(See also: Difference between Python's collections.Counter and nltk.probability.FreqDist)

Final finally, printing it out to file, you should really use a context manager, http://eigenhombre.com/introduction-to-context-managers-in-python.html

with open('bigrams-list.tsv', 'w') as fout:
    for bg, count in FreqDist(ngrams(tokens, 2)).most_common():
        print('\t'.join([' '.join(bg), str(count)]), end='\n', file=fout)

[bigrams-list.tsv]:

looked far  4
far looked  3
visual held 2
held memory 2
memory Little   2
Little little   2
little returned 2
returned waking 2
waking nurse    2
pure amnesia    1
amnesia face    1
face newborn    1
newborn looked  1
far visual  1
nurse visual    1

Food for thought

Now you see this strange bigram Little little, does it make sense?

It's a by-product of removing by from

Little by little

So now, depending on what's the ultimate task for the ngrams you've extracted, you might not really want to remove stopwords from the list.

Answer from alvas on Stack Overflow
Top answer
1 of 2
9

A better question would have been what are those ("()", "'",",") in the ngrams output?

>>> from nltk import ngrams
>>> from nltk import word_tokenize

# Split a sentence into a list of "words"
>>> word_tokenize("This is a foo bar sentence")
['This', 'is', 'a', 'foo', 'bar', 'sentence']
>>> type(word_tokenize("This is a foo bar sentence"))
<class 'list'>

# Extract bigrams.
>>> list(ngrams(word_tokenize("This is a foo bar sentence"), 2))
[('This', 'is'), ('is', 'a'), ('a', 'foo'), ('foo', 'bar'), ('bar', 'sentence')]

# Okay, so the output is a list, no surprise.
>>> type(list(ngrams(word_tokenize("This is a foo bar sentence"), 2)))
<class 'list'>

But what type is ('This', 'is')?

>>> list(ngrams(word_tokenize("This is a foo bar sentence"), 2))[0]
('This', 'is')
>>> first_thing_in_output = list(ngrams(word_tokenize("This is a foo bar sentence"), 2))[0]
>>> type(first_thing_in_output)
<class 'tuple'>

Ah, it's a tuple, see https://realpython.com/python-lists-tuples/

What happens when you print a tuple?

>>> print(first_thing_in_output)
('This', 'is')

What happens if you convert them into a str()?

>>> print(str(first_thing_in_output))
('This', 'is')

But I want the output This is instead of ('This', 'is'), so I will use the str.join() function, see https://www.geeksforgeeks.org/join-function-python/:

>>> print(' '.join((first_thing_in_output)))
This is

Now this is a good point to really go through the tutorial of basic Python types to understand what is happening. Additionally, it'll be good to understand how "container" types work too, e.g. https://github.com/usaarhat/pywarmups/blob/master/session2.md


Going through the original post, there are quite some issues with the code.

I guess the goal of the code is to:

  • Tokenize the text and remove stopwords
  • Extract ngrams (without stopwords)
  • Print out their string forms and their counts

The tricky part is the stopwords.words('english') does not contain punctuation, so you'll end up with strange ngrams that contains punctuations:

from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english'))

tokens = [token for token in nltk.word_tokenize(text) if token not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('The', 'pure'),
 ('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', ','),
 (',', 'newborn'),
 ('newborn', '.'),
 ('.', 'I'),
 ('I', 'looked'),
 ('looked', 'far'),
 ('far', ','),
 (',', ','), ...]

Perhaps you would like to extend the stoplist with punctuations, e.g.

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('The', 'pure'),
 ('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', 'newborn'),
 ('newborn', 'I'),
 ('I', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'), ...]

Then you realized that tokens like I should be a stopword but still exists in your list of ngrams. It's because the list from stopwords.words('english') are lowercased, e.g.

>>> stopwords.words('english')

[out]:

['i',
 'me',
 'my',
 'myself',
 'we',
 'our',
 'ours',
 'ourselves',
 'you',
 "you're", ...]

So when you're checking whether a token is in the stoplist, you should also lowercase the token. (Avoid lowercasing the sentence before word_tokenize because word_tokenize may take cues from capitalization). Thus:

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token.lower() not in stoplist]

list(ngrams(tokens, 2))

[out]:

[('pure', 'amnesia'),
 ('amnesia', 'face'),
 ('face', 'newborn'),
 ('newborn', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'),
 ('looked', 'far'),
 ('far', 'looked'), ...]

Now the ngrams looks like it's achieving the objectives:

  • Tokenize the text and remove stopwords
  • Extract ngrams (without stopwords)

Then on the last part where you want to print out the ngrams to a file in sorted order, you could actually use the Freqdist.most_common() which will list in descending order, e.g.

from string import punctuation
from nltk import word_tokenize
from nltk.util import ngrams
from nltk.corpus import stopwords
from nltk import FreqDist

text = '''The pure amnesia of her face,
newborn. I looked so far into her that, for a while, looked so far into her that, for a while  looked so far into her that, for a while looked so far into her that, for a while the visual 
held no memory. Little by little, I returned to myself, waking to nurse the visual held no  memory. Little by little, I returned to myself, waking to nurse
'''

stoplist = set(stopwords.words('english') + list(punctuation))

tokens = [token for token in nltk.word_tokenize(text) if token.lower() not in stoplist]

FreqDist(ngrams(tokens, 2)).most_common()

[out]:

[(('looked', 'far'), 4),
 (('far', 'looked'), 3),
 (('visual', 'held'), 2),
 (('held', 'memory'), 2),
 (('memory', 'Little'), 2),
 (('Little', 'little'), 2),
 (('little', 'returned'), 2),
 (('returned', 'waking'), 2),
 (('waking', 'nurse'), 2),
 (('pure', 'amnesia'), 1),
 (('amnesia', 'face'), 1),
 (('face', 'newborn'), 1),
 (('newborn', 'looked'), 1),
 (('far', 'visual'), 1),
 (('nurse', 'visual'), 1)]

(See also: Difference between Python's collections.Counter and nltk.probability.FreqDist)

Final finally, printing it out to file, you should really use a context manager, http://eigenhombre.com/introduction-to-context-managers-in-python.html

with open('bigrams-list.tsv', 'w') as fout:
    for bg, count in FreqDist(ngrams(tokens, 2)).most_common():
        print('\t'.join([' '.join(bg), str(count)]), end='\n', file=fout)

[bigrams-list.tsv]:

looked far  4
far looked  3
visual held 2
held memory 2
memory Little   2
Little little   2
little returned 2
returned waking 2
waking nurse    2
pure amnesia    1
amnesia face    1
face newborn    1
newborn looked  1
far visual  1
nurse visual    1

Food for thought

Now you see this strange bigram Little little, does it make sense?

It's a by-product of removing by from

Little by little

So now, depending on what's the ultimate task for the ngrams you've extracted, you might not really want to remove stopwords from the list.

2 of 2
0

So just to "fix" your output: Use this to print your data:

for kk,vv in tmp:
    print(" ".join(list(kk)),",%d" % vv)

BUT if you are going to parse this into an csv you should collect your output in a different format.

Currently you are creating a list of tupels containing a tupel and a number. try to collect your data as a list of lists containing each value. That way you can just write it directly into an csv file.

Take a look here: Create a .csv file with values from a Python list

🌐
YouTube
youtube.com › codewise
remove special characters from string python nltk - YouTube
Download this code from https://codegive.com Title: Removing Special Characters from a String in Python using NLTKIntroduction:In this tutorial, we will expl...
Published   February 2, 2024
Views   26
🌐
Medium
medium.com › @maheshpardeshi002 › removing-special-characters-or-tags-from-text-in-data-pre-processing-using-python-5fa62f886956
Removing special characters or tags from Text in data pre-processing using Python. | by Mahesh Pardeshi | Medium
July 2, 2019 - In this blog, we will see some of the data pre-processing techniques in Python. Removing Stopwards from Text. from nltk.corpus import stopwords stop_words = set(stopwords.words('english')) def removeStopWords(text): sents=[] [stop_words.add(commonWd) for commonWd in commonStopwords] for i in range(len(sent)): word_tokens = word_tokenize(sent[i]) filtered_sentence = [w for w in word_tokens if not w in stop_words] sents.append(' '.join(map(str, filtered_sentence))) return sents
🌐
datagy
datagy.io › home › python posts › python strings › python: remove special characters from a string
Python: Remove Special Characters from a String • datagy
December 17, 2022 - Learn how to use Python to remove special characters from a string, including how to do this using regular expressions and isalnum.
🌐
Linux Hint
linuxhint.com › remove-special-characters-string-python-2
Remove Special Characters from String Python – Linux Hint
The “isalnum()” method deletes the unwanted characters from a string in Python. It returns “True” when all the existing characters in the input string are alphabets or numbers. On the other hand, it will return a “False” value if any special character is found in the input string.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python-removing-unwanted-characters-from-string
Remove Special Characters from String in Python - GeeksforGeeks
April 12, 2025 - Removing multiple characters from a string in Python can be achieved using various methods, such as str.replace(), regular expressions, or list comprehensions. Each method serves a specific use case, and the choice depends on your requirements.
🌐
Medium
medium.com › @blueberry92450 › three-ways-to-remove-special-characters-from-string-in-python-da1035cc93b8
Three ways to Remove Special Characters from String in Python Including Time Comparison | Medium
August 8, 2022 - %timeit string_filtered = re.sub(r”[^a-zA-Z0–9]”,””,string) # returns: 1.74 µs ± 69.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)print(f”re.sub: {string_filtered}”) # returns: re.sub: HelloImSharon · Using replace built in method in python requires a customized function.
🌐
Scaler
scaler.com › home › topics › remove special characters from string python
Remove Special Characters From String Python - Scaler Topics
January 6, 2024 - The string.isalnum() method returns True if all the characters in the string are alphabets or numbers and returns False if it finds any special character in the string. We can use this property to remove all special characters from a string in python.
🌐
Medium
medium.com › @ryan_forrester_ › remove-special-characters-from-strings-in-python-complete-guide-53651c8163d9
Remove Special Characters from Strings in Python: Complete Guide | by ryan | Medium
January 7, 2025 - The `strip()` method is perfect for cleaning up the beginning and end of strings. When you need more control over character removal, regular expressions are your friend. Here’s a practical example: import re def clean_text(text): # Removes ...
🌐
Kaggle
kaggle.com › general › 233576
Remove Special Characters from Text, EXCEPT @'s and #'s - Python | Kaggle
Hello Everyone, I have some really messy text that I'm trying analyze, example below. "@KYMFAFO She’s so pretty!! You’re 1 lucky guy #babe" I was able to...
🌐
Quora
quora.com › How-do-I-remove-all-special-characters-in-a-string-in-Python
How to remove all special characters in a string in Python - Quora
Answer (1 of 5): There are numerous ways to accomplish this. To remove, say, all the a’s from a string, one can use the replace() string method: [code]>>> s = 'A man, a plan, a canal: Panama' >>> s = s.replace('a', '') >>> s 'A mn, pln, cnl: Pnm' [/code]One could also “explode” the string ...
🌐
Javatpoint
javatpoint.com › how-to-remove-all-special-characters-from-a-string-in-python
How to Remove All Special Characters from a String in Python - Javatpoint
April 21, 2023 - How to Remove All Special Characters from a String in Python with tutorial, tkinter, button, overview, canvas, frame, environment set-up, first python program, etc.
🌐
NLTK
nltk.org › book_1ed › ch03.html
Nltk
To prompt the user to type a line of input, call the Python function raw_input(). After saving the input to a variable, we can manipulate it just as we have done for other strings. 3.1 summarizes what we have covered in this section, including the process of building a vocabulary that we saw in 1. (One step, normalization, will be discussed in 3.6). Figure 3.1: The Processing Pipeline: We open a URL and read its HTML content, remove the markup and select a slice of characters; this is then tokenized and optionally converted into an nltk.Text object; we can also lowercase all the words and extract the vocabulary.