2017-03-15 10 views
0

の第一及び第二の要素の数、A、C実行非常に大きなリストA、C、A、D、A、B、C、D与えられたリスト

どのように私は、現在のカウントを取得することができます要素と次は効率的ですか?

AC、 CA、 AD、 DA、 AB、 BC、 CD、 DA、 AC

A : {A:0, B:1, C:2, D:1} 
B : {A:0, B:0, C:1, D:0} 
C : {A:1, B:0, C:0, D:1} 
D : {A:2, B:0, C:0, D:0} 

または私はそれを印刷した場合、:何かのようにそれは生産するでしょう:

A B C D 
A  1 2 1 

B   1 

C 1   1 

D 2 

答えて

4

あなたの入力が大規模で不明な長さ(場合によってはストリーミング)があり、イテレーターを使用するのが理想的です。すべての可能な入力項目の集合を知っていると仮定していないので、出力表にはゼロカウントの項目は含まれていません。

from itertools import tee, izip 

# from http://stackoverflow.com/questions/5764782/iterate-through-pairs-of-items-in-a-python-list 
def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return izip(a, b) 

inp = ['A', 'C', 'A', 'D', 'A', 'B', 'C', 'D', 'A', 'C'] 

table = {} 
for a, b in pairwise(inp): 
    table.setdefault(a, {}) 
    table[a].setdefault(b, 0) 
    table[a][b] += 1 

print(table) 
+0

設定のデフォルトを出力します) 'の代わりに' {} 'を使用しているため、欠落しているキーを時折アクセスすると、OPのように0が返され、カウンタは0カウントで初期化されるため、2番目の 'setdefault'が不要になります。 –

2

あなたはCountersの辞書を使用することができます。

from collections import Counter 
import itertools 

myList = ['A', 'C', 'A', 'D', 'A', 'B', 'C', 'D', 'A', 'C'] 

d = {x:Counter() for x in set(myList)} 

for x,y in zip(myList,itertools.islice(myList,1,None)): 
    d[x].update(y) 

print(d) 

出力:

{'B': Counter({'C': 1}), 'A': Counter({'C': 2, 'B': 1, 'D': 1}), 'C': Counter({'A': 1, 'D': 1}), 'D': Counter({'A': 2})} 

それは特にitertools.islice()を使用してのRawingの優れたアイデア@取り入れた後、Pythonの3合理的に効率的です。私が上でそれをテストした:

myList = [random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ") for i in range(10**6)] 

、それが最初の場所でリストを構築するのに費やした時間よりも小さい、私のマシン上の約半分秒かかります。

+2

リストを複製しないようにするには、 'myList [1:]'は 'itertools.islice(myList、1、None)'でなければなりません。 (OPはそれが非常に大きいと述べているので) –

+0

@Rawingそれは良い考えです。 100万エントリの例では、スピードアップはわずかでしたが目立ちました。間違いなく、メモリがより効率的であることは言うまでもありませんが、サイズがさらに大きくなるにつれて、それはより重要になるでしょう。ありがとう。 –

1

あなたは要素の出現をカウントして、2D辞書にそれを変換するためにcollections.Counterを使用することができます。

import itertools 
from collections import Counter 

l = ['A', 'C', 'A', 'D', 'A', 'B', 'C', 'D', 'A', 'C'] 

# create a list of pairs of neighboring elements 
neighbors = zip(l, itertools.islice(l, 1, None)) 

# count occurrences  
counts = Counter(neighbors) 

# convert counts to a 2D dictionary 
output = {} 
for k in counts: 
    if k[0] not in output: 
     output[k[0]] = {} 
    output[k[0]][k[1]] = counts[k] 
print(output) 

これは `カウンター(へ

{'C': {'D': 1, 'A': 1}, 'D': {'A': 2}, 'A': {'C': 2, 'D': 1, 'B': 1}, 'B': {'C': 1}} 
関連する問題