4

リストがあります。かなり大きいです。100万件以上のエントリーがあります。その中の各文字列の頻度を数えたいと思います。数値を 1 から 1000 までの文字列として保存します。以下を使用しましたが、何時間も実行し続けます。

d = {b:a.count(b) for b in a}
n, m = d.keys(), d.values()
print n, m
4

3 に答える 3

9

collections.Counter代わりに使用してください:

from collections import Counter
d = Counter(a)

n, m = d.keys(), d.values()
print n, m
于 2013-10-08T04:02:34.173 に答える
2

この場合、辞書を使用する方がはるかに簡単だと思います。ディクショナリへの挿入は非常に高速で、ディクショナリからの取得も同様に高速です。

これを正確に実行するサンプル プログラムを次に示します。

import datetime
import random
def create_string(choice, size):
    str = ''
    for i in range(size):
         str = str + random.choice(choice)
    return str

def count_all(strings):
    count_dict = {}
    for i in strings:
        if i not in count_dict:
            count_dict[i] = 1
        else:
            count_dict[i] = count_dict[i] + 1
    return count_dict

if __name__ == '__main__':
    all_strings = []
    for i in range(1000000):
        all_strings.append(create_string(['a','b','c'], 4))

    start = datetime.datetime.now()
    c_dict = count_all(all_strings)
    end = datetime.datetime.now()
    print 'Took:', end - start
    print 'The count of aacc is ', c_dict['aacc']

そして、それはどのように公平ですか?

./speed_test.py
Took: 0:00:00.219815
The count of aacc is  12317

全然悪くないですよね?別のオプションとして、Ant が言及した問題を解決するには、カウントを行うときに重複を取り除きたいと考えています。そのためにセットを使用できます。

d = {b:a.count(b) for b in set(a)}

私のテストによると、これはディクショナリ メソッドほど高速ではありませんが、1 秒未満なので十分です。

于 2013-10-08T20:43:07.480 に答える
1

すべての文字列に対して a.count を実行しているため、遅いです!

l = ['a', 'b', 'a']

その後str.count、'a' で 2 回、'b' で 1 回呼び出されます。

もちろん、「a」の 2 回目では、辞書の結果がオーバーライドされるだけなので、気付かないこともあります。

代わりにデフォルトの辞書を使用してください

from collections import defaultdict
d = defaultdict(int)
for obj in your_list:
    d[obj] += 1

または、再びコレクションモジュールから、Counter http://docs.python.org/2/library/collections.html#counter-objects

于 2013-10-08T04:03:08.237 に答える