リストがあります。かなり大きいです。100万件以上のエントリーがあります。その中の各文字列の頻度を数えたいと思います。数値を 1 から 1000 までの文字列として保存します。以下を使用しましたが、何時間も実行し続けます。
d = {b:a.count(b) for b in a}
n, m = d.keys(), d.values()
print n, m
リストがあります。かなり大きいです。100万件以上のエントリーがあります。その中の各文字列の頻度を数えたいと思います。数値を 1 から 1000 までの文字列として保存します。以下を使用しましたが、何時間も実行し続けます。
d = {b:a.count(b) for b in a}
n, m = d.keys(), d.values()
print n, m
collections.Counter
代わりに使用してください:
from collections import Counter
d = Counter(a)
n, m = d.keys(), d.values()
print n, m
この場合、辞書を使用する方がはるかに簡単だと思います。ディクショナリへの挿入は非常に高速で、ディクショナリからの取得も同様に高速です。
これを正確に実行するサンプル プログラムを次に示します。
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 秒未満なので十分です。
すべての文字列に対して 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