2017-03-15 51 views
0

的第一和第二要素的數量,C,A,d,A,B,C,d,A,C運行給予了非常大名單一個列表

我怎樣才能得到當前的計數元素和下一個有效?喜歡的東西:

交流, 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

設置默認爲'計數器() '而不是'{}',因此偶爾訪問丟失的鍵會返回0,如同在OP中一樣,並且也不需要第二個'setdefault',因爲計數器初始化爲0計數。 –

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})} 

它是在Python 3合理有效,尤其是結合@ Rawing的使用itertools.islice()的好主意後。我對它進行了測試:

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

並且在我的機器上花費了大約半秒的時間,比首先構建列表花費的時間少。

+2

'myList [1:]'應該是'itertools.islice(myList,1,None)'以避免重複列表。 (由於OP已經聲明它非常大) –

+0

@Rawing這是個好主意。以100萬條記錄爲例,加速比較輕微但很明顯。毫無疑問,隨着規模越來越大,它變得越來越重要,更不用說記憶效率更高了。謝謝。 –

1

你可以使用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}}