繰り返しアイテムのリストがあり、ユニークなアイテムとその頻度のリストが必要です。
たとえば、_['a', 'a', 'b', 'b', 'b']
_があり、[('a', 2), ('b', 3)]
が必要です。
2回ループすることなくこれを行う簡単な方法を探しています。
アイテムがグループ化されている(つまり、類似したアイテムがまとまって集まっている)場合、最も効率的な方法はitertools.groupby
:
>>> [(g[0], len(list(g[1]))) for g in itertools.groupby(['a', 'a', 'b', 'b', 'b'])]
[('a', 2), ('b', 3)]
Python 2.7+では、 collections.Counter
。
それ以外の場合は、 このカウンターのレシピ を参照してください。
Python 2.7+:
from collections import Counter
input = ['a', 'a', 'b', 'b', 'b']
c = Counter( input )
print( c.items() )
出力は次のとおりです。
[( 'a'、2)、( 'b'、3)]
>>> mylist=['a', 'a', 'b', 'b', 'b']
>>> [ (i,mylist.count(i)) for i in set(mylist) ]
[('a', 2), ('b', 3)]
サードパーティのライブラリを使用する場合は、NumPyが便利なソリューションを提供します。これは、リストに数値データのみが含まれている場合に特に効率的です。
import numpy as np
L = ['a', 'a', 'b', 'b', 'b']
res = list(Zip(*np.unique(L, return_counts=True)))
# [('a', 2), ('b', 3)]
構文を理解するには、 np.unique
ここでは、一意の値とカウントのタプルを返します。
uniq, counts = np.unique(L, return_counts=True)
print(uniq) # ['a' 'b']
print(counts) # [2 3]
「古い方法」。
>>> alist=['a', 'a', 'b', 'b', 'b']
>>> d={}
>>> for i in alist:
... if not d.has_key(i): d[i]=1 #also: if not i in d
... else: d[i]+=1
...
>>> d
{'a': 2, 'b': 3}
私はこれがワンライナーではないことを知っています...しかし、私はそれが好きです(countを呼び出すのではなく)最初の値のリストを一度渡すことは私にとって明らかであるためです:
>>> from collections import defaultdict
>>> l = ['a', 'a', 'b', 'b', 'b']
>>> d = defaultdict(int)
>>> for i in l:
... d[i] += 1
...
>>> d
defaultdict(<type 'int'>, {'a': 2, 'b': 3})
>>> list(d.iteritems())
[('a', 2), ('b', 3)]
>>>
pandasの助けを借りて、あなたは次のようにすることができます:
import pandas as pd
dict(pd.value_counts(my_list))
ハッシュなしのソリューション:
def lcount(lst):
return reduce(lambda a, b: a[0:-1] + [(a[-1][0], a[-1][1]+1)] if a and b == a[-1][0] else a + [(b, 1)], lst, [])
>>> lcount([])
[]
>>> lcount(['a'])
[('a', 1)]
>>> lcount(['a', 'a', 'a', 'b', 'b'])
[('a', 3), ('b', 2)]
データ構造をpandas series sに変換します。
コード:
for i in sort(s.value_counts().unique()):
print i, (s.value_counts()==i).sum()
これを行う別の方法は
mylist = [1, 1, 2, 3, 3, 3, 4, 4, 4, 4]
mydict = {}
for i in mylist:
if i in mydict: mydict[i] += 1
else: mydict[i] = 1
次にタプルのリストを取得するには、
mytups = [(i, mydict[i]) for i in mydict]
これはリストを1回だけ超えますが、辞書を1回走査する必要もあります。ただし、リストに多くの重複があることを考えると、ディクショナリははるかに小さくなり、トラバースが高速になります。
それにもかかわらず、非常にきれいなコードや簡潔なコードではないことを認めます。
これが1つの方法です。
your_list = ['a', 'a', 'b', 'b', 'b']
count_dictionary = {}
for letter in your_list:
if letter in count_dictionary:
count_dictionary[letter] +=1
else:
count_dictionary[letter] = 1