Je travaille avec une liste de tuples, comme ci-dessous:
29 7 22 5
Je recherche une sortie qui affichera le nombre de noms, verbes, adjectifs et autres mots dans cette liste de tuples, avec les critères suivants:
Jusqu'à présent, j'ai:
cnts = [cnt_noun, cnt_vb, cnt_adj, cnt_other] for x in cnts: print(x)
Et cela affiche correctement les décomptes:
# 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
Rendements
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')]
Il est important de renvoyer les décomptes de chaque balise de mot dans sa totalité, car cela sera utilisé dans le cadre d'une grande séquence de construction de données.
Cependant, y a-t-il une manière plus pythonique d'accomplir la même chose, avec moins de lignes et plus efficacement?
3 Réponses :
J'utiliserais probablement des collections.Counter:
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})
Voici une solution complète:
res = [('stori', 'JJ'), ('man', 'NN'), ...] counter = Counter([b for a, b in res]) # Counter acts like a dictionary containing e.g. {'JJ': 3, ...}
Pas le downvoter, probablement pas le résultat attendu.
Je n'ai pas non plus voté contre, mais cela ne correspond pas au résultat attendu.
Je comprends que cela ne correspond pas à la sortie bien que je pense que c'est la première étape pour l'OP
Le code que j'ai posté produit le résultat attendu, c'est franchement inefficace et non pythonique. Mais, c'est quelque chose à examiner certainement, merci.
@wwii Si vous relisez le code d'OP, ce n'est pas exactement ce que OP veut.
Vous pouvez utiliser collections.defaultdict
et le rendre plus propre:
Adj 22 Noun 29 Verb 7 Others 5
Quelles sorties:
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))
p >
collections.Counter est la voie à suivre.
'other'
pour tout ce qui n'est pas défini. >>> c Counter({'noun': 29, 'adjective': 22, 'verb': 7, 'other': 5}) >>>
En tant que boucle for:
c = collections.Counter() for word,quality in res: c.update(stuff.get(quality[:2],'other'))
import collections stuff = {'NN':'noun', 'JJ':'adjective','VB':'verb','VP':'verb'} c = collections.Counter(stuff.get(thing[:2],'other') for word,thing in res)
Vous souciez-vous de la sortie intermédiaire comme
print ("Verb: {}". Format (tpl))
?@HansMusgrave franchement pas tellement, était là plus pour s'assurer que le code fonctionnait correctement, je devrais le supprimer.
En utilisant
elif ('VB' dans tpl [1] ou 'VP' dans tpl [1]):
, vous comptez pour'VBP'
,'VBN '
aussi. Est-ce prévu?@Austin oui, car les deux commencent
VB
et / ouVP
. La séquence de caractères restante n'est pas pertinente; c'est ce par quoi il commence qui est important.