將列表列表減少為字典,以子列表大小為鍵,出現次數為值 (Reduce list of list to dictionary with sublist size as keys and number of occurances as value)


問題描述

將列表列表減少為字典,以子列表大小為鍵,出現次數為值 (Reduce list of list to dictionary with sublist size as keys and number of occurances as value)

我有一個列表列表,我想計算具有特定大小的子列表出現的次數。

例如。對於列表 [[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, {}))

## 參考解法 #### 方法 1:

It is not a good idea to use reduce in such a complicated way when you can use collections.Counter() with map() function in a more Pythonic way:

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

Note that using map will perform slightly better than a generator expression because by passing a generator expression to Counter() python will get the values from generator function by itself, since using built‑in function map has more performance in terms of execution time1.

~$ 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

From PEP 0289 ‑‑ Generator Expressions:

The semantics of a generator expression are equivalent to creating an anonymous generator function and calling it. For example:

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

is equivalent to:

def __gen(exp):
    for x in exp:
        yield x**2
g = __gen(iter(range(10)))
print g.next()

Note that since generator expressions are better in terms of memory use, if you are dealing with large data you'd better use generator expression instead of map function.

方法 2:

You can do this using Counter as well:

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

Output:

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

方法 3:

reduce is an inferior tool for this job.

Look at a collections.Counter instead. It's a dict subclass, so you should be able to use it however you were planning to use the 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})

(by WojciechKoMazdakidjawwim)

參考文件

  1. Reduce list of list to dictionary with sublist size as keys and number of occurances as value (CC BY‑SA 2.5/3.0/4.0)

#lambda #reduce #Python #Dictionary






相關問題

Lambda 表達式中的 SQL WHERE 等價物是什麼? (What's the equivalence of an SQL WHERE in Lambda expressions?)

如何將 lambda 傳遞給 Razor 輔助方法? (How to pass in a lambda to a Razor helper method?)

lỗi biểu thức lambda: biểu thức phải là giá trị có thể sửa đổi (lambda expression error: expression must be a modifiable lvalue)

如何在 PySpark 中有效地按值排序? (How to sort by value efficiently in PySpark?)

將列表列表減少為字典,以子列表大小為鍵,出現次數為值 (Reduce list of list to dictionary with sublist size as keys and number of occurances as value)

匿名類作為泛型參數 (anonymous class as generic parameter)

如何為 lambda 中的運算符賦予不定性? (How to give infixities to operators in lambda?)

如何發出委託或 lambda 表達式 (Howto emit a delegate or lambda expression)

深入學習 C# 表達式樹的最佳資源是什麼? (What is the best resource for learning C# expression trees in depth?)

根據最高日期從 IGrouping 中獲取項目 (Get an item from a IGrouping based on the highest date)

如何在 C# 中使用“param”來獲取這個示例? (How can I get this example using "param" in C# to work?)

如何使用 C# 中的 Lambda 表達式僅返回沒有來自另一個表的行的行 (How to return only rows where no rows from another table using Lambda Expressions in C#)







留言討論