[英]Incrementing dict values with dict comprehension
我正在嘗試使用dict理解和python中的三元運算來執行以下表達式:
for num in ar:
if num in seen_dict:
seen_dict[num] += 1
else:
seen_dict[num] = 1
我嘗試了這個:
seen_dict = { num: seen_dict[num] += 1 for num in ar if num in seen_dict else seen_dict[num] = 1}
及其幾個排列,但我不斷收到語法錯誤。 可以做我想做的嗎?
更新
這是正確的語法,但我的dict並非僅返回1:: seen_dict = { num: (seen_dict[num] + 1) if num in seen_dict else 1 for num in ar }
有人可以解釋為什么這與for循環的功能不同嗎? 謝謝。
別。 似乎使用dict理解應該是一個好主意,但這實際上是一個可怕的陷阱。 使用collections.Counter
:
import counts
seen_dict = collections.Counter(ar)
或者,如果您不想這樣做,請堅持循環。
嘗試使用dict理解的問題是dict理解沒有良好的方式來維持狀態或交錯每個鍵的值的計算。 每個值必須在單個表達式中計算。 相反,解決計數問題的最佳方法是對ar
進行一次傳遞,並隨需更新每個元素的計數。
理解的限制會導致效率極低的嘗試,例如
seen_dict = {val: ar.count(val) for val in ar}
這使得若干越過的ar
等於長度ar
,或稍微更有效,但仍可怕次優
seen_dict = {val: ar.count(val) for val in set(ar)}
只需傳遞len(set(ar))
,或者對於更熟悉標准庫的人來說 ,
from itertools import groupby
seen_dict = {val: sum(1 for _ in group) for val, group in groupby(sorted(ar))}
至少不是二次時間,但長度為n ar
仍為O(nlogn)。
如果我們使用輸入list(range(10000))
對這四個代碼片段進行計時 :
from collections import Counter
from itertools import groupby
from timeit import timeit
ar = list(range(10000))
print(timeit('Counter(ar)', number=1, globals=globals()))
print(timeit('{val: ar.count(val) for val in ar}', number=1, globals=globals()))
print(timeit('{val: ar.count(val) for val in set(ar)}', number=1, globals=globals()))
print(timeit('{val: sum(1 for _ in group) for val, group in groupby(sorted(ar))}',
number=1, globals=globals()))
我們得到以下輸出:
0.0005530156195163727
1.0503493696451187
1.0463058911263943
0.00422721728682518
Counter
在半毫秒內完成,而count
片段都占用一秒以上。 (該set
版本似乎具有較低的運行時由於某種首次運行效果減慢其他版本;交換的順序set
和非set
版本通常逆轉這些版本的相對定時的重復數據刪除。 set
沒有按由於輸入沒有重復項,因此對測試沒有幫助。)
對於更長的輸入,依賴count
將更加昂貴。 依靠count
可能很容易需要幾天的時間, Counter
仍會在一秒鍾之內完成輸入。
在這里,它實際上比我想象的要簡單。 基本上,您想要的是列表中某件事發生的次數,您可以通過說ar.count(num)
。 您可以輕松地做到這一點,而無需三元運算符,例如:
ar = [1,2,3,2]
seen_dict = { num:ar.count(num) for num in ar}
print(seen_dict)# {1:1, 2:2, 3:1}
似乎您正在嘗試獲取列表中所有值的外觀。 (如果不是,請讓我知道。)這是我將如何處理的方法:
seen_dict = {num: arr.count(num) for num in list(set(arr))}
一個解釋:
arr.count(num)
: list.count(element)
方法返回list
中element
的出現次數 set(arr)
:創建一個set
對象,將其轉換回列表時將刪除所有重復項,換句話說,將獲取列表的所有不同值 list(set(arr))
在不同的值arr
字典回報將有鍵值對number
- # of appearances of number in arr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.