Reputation: 7281
I am working with a list of tuples, like below:
res = [('stori', 'JJ'), ('man', 'NN'), ('unnatur', 'JJ'), ('feel', 'NN'), ('pig', 'JJ'), ('start', 'NN'), ('open', 'JJ'), ('scene', 'NN'), ('terrif', 'NN'), ('exampl', 'NN'), ('absurd', 'JJ'), ('comedi', 'NN'), ('formal', 'JJ'), ('orchestra', 'NN'), ('audienc', 'NN'), ('turn', 'VBP'), ('insan', 'JJ'), ('violent', 'JJ'), ('mob', 'NN'), ('crazi', 'NN'), ('chant', 'JJ'), ('singer', 'NN'), ('unfortun', 'JJ'), ('stay', 'NN'), ('absurd', 'IN'), ('whole', 'JJ'), ('time', 'NN'), ('general', 'JJ'), ('narrat', 'NN'), ('eventu', 'VBP'), ('make', 'VBP'), ('put', 'VB'), ('even', 'RB'), ('era', 'NN'), ('turn', 'NN'), ('cryptic', 'JJ'), ('dialogu', 'NN'), ('would', 'MD'), ('make', 'VB'), ('shakespear', 'JJ'), ('seem', 'JJ'), ('easi', 'JJ'), ('third', 'JJ'), ('grader', 'NN'), ('technic', 'JJ'), ('level', 'NN'), ('better', 'RBR'), ('might', 'MD'), ('think', 'VB'), ('good', 'JJ'), ('cinematographi', 'NN'), ('futur', 'NN'), ('great', 'JJ'), ('vilmo', 'JJ'), ('zsigmond', 'NN'), ('futur', 'NN'), ('star', 'NN'), ('salli', 'NN'), ('kirkland', 'NN'), ('freder', 'NN'), ('forrest', 'JJS'), ('seen', 'VBN'), ('briefli', 'NN')]
I am looking for an output that will show the count of nouns, verbs, adjectives, and other words in this list of tuples, with the following criteria:
So far I have:
# Create a set of all values that appear
appears = set([x[1] for x in res])
cnt_noun = 0
cnt_adj = 0
cnt_vb = 0
cnt_other = 0
for tpl in res:
if('NN' in tpl[1]):
cnt_noun += 1
elif('JJ' in tpl[1]):
cnt_adj += 1
elif('VB' in tpl[1] or 'VP' in tpl[1]):
cnt_vb += 1
else:
cnt_other += 1
And that properly displays the counts:
cnts = [cnt_noun, cnt_vb, cnt_adj, cnt_other]
for x in cnts:
print(x)
Yields
29
7
22
5
It is important to actually return the counts by each word tag in totality, as this will be used as part of a large data building sequence.
However, is there a more pythonic way to accomplish the same thing, with less lines and more efficiently?
Upvotes: 2
Views: 96
Reputation: 26037
You can use collections.defaultdict
and make it cleaner:
d = defaultdict(list)
for x, y in res:
if 'VB' in y or 'VP' in y:
y = 'Verb'
elif 'JJ' in y:
y = 'Adj'
elif 'NN' in y:
y = 'Noun'
else:
y = 'Others'
d[y].append(x)
for k, v in d.items():
print(k, len(v))
Which outputs:
Adj 22
Noun 29
Verb 7
Others 5
Upvotes: 1
Reputation: 1275
I'd probably use collections.Counter:
res = [('stori', 'JJ'), ('man', 'NN'), ...]
counter = Counter([b for a, b in res])
# Counter acts like a dictionary containing e.g. {'JJ': 3, ...}
Here take a look at a complete solution:
from collections import Counter
res = [('stori', 'JJ'), ('man', 'NN'), ('unnatur', 'JJ'), ('feel', 'NN'), ('pig', 'JJ'), ('start', 'NN'), ('open', 'JJ'), ('scene', 'NN'), ('terrif', 'NN'), ('exampl', 'NN'), ('absurd', 'JJ'), ('comedi', 'NN'), ('formal', 'JJ'), ('orchestra', 'NN'), ('audienc', 'NN'), ('turn', 'VBP'), ('insan', 'JJ'), ('violent', 'JJ'), ('mob', 'NN'), ('crazi', 'NN'), ('chant', 'JJ'), ('singer', 'NN'), ('unfortun', 'JJ'), ('stay', 'NN'), ('absurd', 'IN'), ('whole', 'JJ'), ('time', 'NN'), ('general', 'JJ'), ('narrat', 'NN'), ('eventu', 'VBP'), ('make', 'VBP'), ('put', 'VB'), ('even', 'RB'), ('era', 'NN'), ('turn', 'NN'), ('cryptic', 'JJ'), ('dialogu', 'NN'), ('would', 'MD'), ('make', 'VB'), ('shakespear', 'JJ'), ('seem', 'JJ'), ('easi', 'JJ'), ('third', 'JJ'), ('grader', 'NN'), ('technic', 'JJ'), ('level', 'NN'), ('better', 'RBR'), ('might', 'MD'), ('think', 'VB'), ('good', 'JJ'), ('cinematographi', 'NN'), ('futur', 'NN'), ('great', 'JJ'), ('vilmo', 'JJ'), ('zsigmond', 'NN'), ('futur', 'NN'), ('star', 'NN'), ('salli', 'NN'), ('kirkland', 'NN'), ('freder', 'NN'), ('forrest', 'JJS'), ('seen', 'VBN'), ('briefli', 'NN')]
mapping = {'NN':'noun', 'JJ':'adjective','VB':'verb','VP':'verb'}
counter = Counter([mapping.get(b[:2], "other") for a, b in res])
print(counter) # Counter({'noun': 29, 'adjective': 22, 'verb': 7, 'other': 5})
Upvotes: 5
Reputation: 23783
collections.Counter is the way to go.
'other'
for anything not defined.import collections
stuff = {'NN':'noun', 'JJ':'adjective','VB':'verb','VP':'verb'}
c = collections.Counter(stuff.get(thing[:2],'other') for word,thing in res)
As a for loop:
c = collections.Counter()
for word,quality in res:
c.update(stuff.get(quality[:2],'other'))
>>> c
Counter({'noun': 29, 'adjective': 22, 'verb': 7, 'other': 5})
>>>
Upvotes: 3