将列表列表缩减为字典,子列表大小为键,出现次数为值

时间:2015-11-16 19:35:21

标签: python dictionary lambda reduce

我有一个列表列表,我想计算出具有特定大小的子列表的次数。

例如。列表[[1], [1,2], [1,2], [1,2,3]]我希望获得{1: 1, 2: 2, 3: 1}

我尝试了reduce函数,但我在+= 1上有语法错误,并且不知道出了什么问题。

list_of_list = [[1], [1,2], [1,2], [1,2,3]]
result = functools.reduce(lambda dict,list: dict[len(list)] += 1, list_of_list, defaultdict(lambda: 0, {}))

3 个答案:

答案 0 :(得分:7)

当您以更加Pythonic的方式使用reducecollections.Counter()函数时,以这种复杂的方式使用map()不是一个好主意:

>>> A = [[1], [1,2], [1,2], [1,2,3]]
>>> from collections import Counter
>>> 
>>> Counter(map(len,A))
Counter({2: 2, 1: 1, 3: 1})

请注意,使用map的性能稍好于生成器表达式,因为通过将生成器表达式传递给Counter(),python将自动从生成器函数中获取值,因为使用内置函数{{ 1}}在执行时间 1 方面具有更高的性能。

map

来自PEP 0289 -- Generator Expressions

  

生成器表达式的语义等同于创建匿名生成器函数并调用它。例如:

~$ python -m timeit --setup "A = [[1], [1,2], [1,2], [1,2,3]];from collections import Counter" "Counter(map(len,A))"
100000 loops, best of 3: 4.7 usec per loop
~$ python -m timeit --setup "A = [[1], [1,2], [1,2], [1,2,3]];from collections import Counter" "Counter(len(x) for x in A)"
100000 loops, best of 3: 4.73 usec per loop
     

相当于:

g = (x**2 for x in range(10))
print g.next()

<子> 请注意,由于生成器表达式在内存使用方面更好,如果您处理大数据,最好使用生成器表达式而不是 map 功能。

答案 1 :(得分:4)

您也可以使用Counter执行此操作:

list_of_list = [[1], [1,2], [1,2], [1,2,3]]
c = Counter(len(i) for i in list_of_list)

输出:

Counter({2: 2, 1: 1, 3: 1})

答案 2 :(得分:1)

reduce是这项工作的劣等工具。

请改为collections.Counter。它是一个dict子类,所以你应该可以使用它,但是你计划使用dict。

>>> from collections import Counter
>>> L = [[1], [1, 2], [1, 2], [1, 2, 3]]
>>> Counter(len(x) for x in L)
Counter({1: 1, 2: 2, 3: 1})