سؤال

افترض أن لدي قائمة بالكلمات، وأريد أن أجد عدد المرات التي تظهر فيها كل كلمة في تلك القائمة.

طريقة واضحة للقيام بذلك هي:

words = "apple banana apple strawberry banana lemon"
uniques = set(words.split())
freqs = [(item, words.split().count(item)) for item in uniques]
print(freqs)

لكنني أجد هذا الرمز غير جيد جدا، لأن البرنامج يعمل عبر قائمة الكلمات مرتين، مرة واحدة لبناء المجموعة، والمرة الثانية لحساب عدد المظاهر.

بالطبع، يمكنني كتابة وظيفة لتشغيلها من خلال القائمة والقيام بالعد، ولكن هذا لن يكون بيثونيك. لذلك، هل هناك طريقة أكثر كفاءة وثبات؟

هل كانت مفيدة؟

المحلول

defaultdict. إلى الإنقاذ!

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"

d = defaultdict(int)
for word in words.split():
    d[word] += 1

هذا يعمل في O (ن).

نصائح أخرى

ال Counter صف دراسي في ال collections الوحدة النمطية مصممة لحل هذا النوع من المشكلة:

from collections import Counter
words = "apple banana apple strawberry banana lemon"
Counter(words.split())
# Counter({'apple': 2, 'banana': 2, 'strawberry': 1, 'lemon': 1})

النهج القياسي:

from collections import defaultdict

words = "apple banana apple strawberry banana lemon"
words = words.split()
result = collections.defaultdict(int)
for word in words:
    result[word] += 1

print result

Groupby Oneliner:

from itertools import groupby

words = "apple banana apple strawberry banana lemon"
words = words.split()

result = dict((key, len(list(group))) for key, group in groupby(sorted(words)))
print result
freqs = {}
for word in words:
    freqs[word] = freqs.get(word, 0) + 1 # fetch and increment OR initialize

أعتقد أن هذا ينتج عنه حل ثلاثيها، ولكن دون استيراد المجموعات. أيضا مثل حل Selinap، ولكن IMHO أكثر قابلية للقراءة. مماثلة تقريبا لحل توماس Weigel، ولكن دون استخدام استثناءات.

قد يكون هذا أبطأ من استخدام DefaultDict () من مكتبة المجموعات. نظرا لأن القيمة جلبت، تزايد ثم تم تعيينها مرة أخرى. بدلا من مجرد زيادة. ومع ذلك باستخدام + = قد تفعل نفس الشيء فقط داخليا.

إذا كنت لا ترغب في استخدام طريقة القاموس القياسية (حلقات من خلال القائمة زيادة DICTEM المناسبة. مفتاح)، يمكنك تجربة هذا:

>>> from itertools import groupby
>>> myList = words.split() # ['apple', 'banana', 'apple', 'strawberry', 'banana', 'lemon']
>>> [(k, len(list(g))) for k, g in groupby(sorted(myList))]
[('apple', 2), ('banana', 2), ('lemon', 1), ('strawberry', 1)]

يعمل في وقت O (N Log N).

دون defaultdict:

words = "apple banana apple strawberry banana lemon"
my_count = {}
for word in words.split():
    try: my_count[word] += 1
    except KeyError: my_count[word] = 1

لا يمكنك فقط استخدام العد؟

words = 'the quick brown fox jumps over the lazy gray dog'
words.count('z')
#output: 1

لقد حدث للعمل على بعض تمرين شرارة، إليك حلاي.

tokens = ['quick', 'brown', 'fox', 'jumps', 'lazy', 'dog']

print {n: float(tokens.count(n))/float(len(tokens)) for n in tokens}

** # إخراج ما ورد أعلاه **

{'brown': 0.16666666666666666, 'lazy': 0.16666666666666666, 'jumps': 0.16666666666666666, 'fox': 0.16666666666666666, 'dog': 0.16666666666666666, 'quick': 0.16666666666666666}

استخدم تقليل () لتحويل القائمة إلى Dict واحد.

words = "apple banana apple strawberry banana lemon"
reduce( lambda d, c: d.update([(c, d.get(c,0)+1)]) or d, words.split(), {})

عائدات

{'strawberry': 1, 'lemon': 1, 'apple': 2, 'banana': 2}
words = "apple banana apple strawberry banana lemon"
w=words.split()
e=list(set(w))       
for i in e:
   print(w.count(i))    #Prints frequency of every word in the list

أتمنى أن يساعدك هذا!

الجواب أدناه يأخذ بعض دورات إضافية، لكنها طريقة أخرى

def func(tup):
    return tup[-1]


def print_words(filename):
    f = open("small.txt",'r')
    whole_content = (f.read()).lower()
    print whole_content
    list_content = whole_content.split()
    dict = {}
    for one_word in list_content:
        dict[one_word] = 0
    for one_word in list_content:
        dict[one_word] += 1
    print dict.items()
    print sorted(dict.items(),key=func)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top