运行列表的第一个和第二个元素的计数

时间:2017-03-15 17:09:23

标签: python list math

给出一个非常大的列表A,C,A,D,A,B,C,D,A,C

如何有效地获取当前元素和下一元素的计数?类似的东西:

AC, CA, 广告, DA, AB, 公元前, 光盘, 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

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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 :(得分:1)

您可以使用collections.Counter计算元素的出现次数,然后将其转换为2D字典:

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