元组列表的频率

时间:2016-11-15 06:26:06

标签: python python-3.x

我有一个清单:

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],...............['3','4'])]

我想创建2列,这些列给出了列表中元组的频率。例如:

bigram      frequency
['7','8']     2
['4','7']     3
['3', '4']    6

等等。

另外,请考虑['7','8']['8','7']之类的条目(重复)。唯一一个条目应该在列中,频率应该添加到该列中。

我正在尝试使用

from collections import counter

并对它进行一些循环,但我收到的错误是:

  

不可用类型:列表

4 个答案:

答案 0 :(得分:3)

列表不可用作字典键,需要将它们转换为可哈希的对象。在这种情况下tuple是合适的选择:

In [5]: Counter(map(tuple, a[0])).items()
Out[5]: 
[(('4', '7'), 1),
 (('4', '8'), 1),
 (('7', '8'), 1),
 (('3', '4'), 2),
 (('3', '8'), 1)]

如果你想要考虑unordere数组,你必须对它们进行排序,然后将它们传递给Counter

In [7]: a
Out[7]: 
[(['7', '8'],
  ['4', '7'],
  ['3', '4'],
  ['3', '8'],
  ['4', '8'],
  ['3', '4'],
  ['7', '4'])]

In [8]: Counter(tuple(sorted(i)) for i in a[0])
Out[8]: Counter({('4', '7'): 2, ('3', '4'): 2, ('3', '8'): 1, ('7', '8'): 1, ('4', '8'): 1})

注意,因为你的数字是字符串,如果它们有多个数字长度你应该在排序之前将它们转换为整数,否则它们将按字典顺序排序。

答案 1 :(得分:3)

试试这个:

from collections import Counter

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['3','4'],['7','8'],['8','7'],['4','3'])]

frequency_list = Counter(tuple(sorted(i)) for i in a[0])

print "bigram","frequency"
for key,val in frequency_list.items():
    print key, val

输出如下

bigram    frequency
('4', '7') 1
('4', '8') 1
('7', '8') 3
('3', '4') 3
('3', '8') 1

答案 2 :(得分:2)

如果您将列表更改为以下内容,它将使用Counter: Counter(map(lambda x: tuple(sorted(x)), a[0])).items()

或者您可以将列表映射到元组,因为元组是可清除的但不是列表。

[更新]排序,然后将每个列表首先映射到元组。 event.subscriber(基于@Kasramvd)。

答案 3 :(得分:0)

我猜您可以使用itertools.groupby对已排序的项目列表进行分组。组的密钥可以是可以创建有序列表的自定义密钥。对于二进制元组,您可以使用简单的比较来创建这样的元组

考虑

a = [(['7', '8'], ['4', '7'],['3', '4'],['3', '8'],['4', '8'],['4','3'])]


from itertools import groupby
key = lambda tup: tup if tup[0] < tup[1] else tup[::-1]
[(key,  len(list(values))) 
 for key, values in groupby(sorted(a[0], key = key), key = key)]
Out[42]: 
[(['3', '4'], 2),
 (['3', '8'], 1),
 (['4', '7'], 1),
 (['4', '8'], 1),
 (['7', '8'], 1)]

如果列表中有两个以上的项目,请考虑使用sorted作为键。这可能效率不高但可以方便

[(key,  len(list(values)))
 for key, values in groupby(sorted(a[0], key = sorted), key = sorted)]
Out[37]: 
[(['3', '4'], 2),
 (['3', '8'], 1),
 (['4', '7'], 1),
 (['4', '8'], 1),
 (['7', '8'], 1)]