我有一个列表列表,我想计算出具有特定大小的子列表的次数。
例如。列表[[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, {}))
答案 0 :(得分:7)
当您以更加Pythonic的方式使用reduce
和collections.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})