[英]How to improve python dict performance?
我最近使用dictoionaries編碼了python解決方案,該字典獲得了TLE裁決。 該解決方案與工作中的c ++中的多集解決方案完全相似。 因此,我們確定邏輯是正確的,但是實現方法不盡人意。
用於理解以下代碼的問題描述( http://codeforces.com/contest/714/problem/C ):
有任何提示/指針可以改善以下代碼的性能嗎? 它為大型測試用例( http://codeforces.com/contest/714/submission/20594344 )授予TLE(超過時間限制)。
from collections import defaultdict
def getPattern(s):
return ''.join(list(s.zfill(19)))
def getSPattern(s):
news = s.zfill(19)
patlist = [ '0' if (int(news[i])%2 == 0) else '1' for i in range(19) ]
return "".join(patlist)
t = int(raw_input())
pat = defaultdict(str) # holds strings as keys and int as value
for i in range(0, t):
oper, num = raw_input().strip().split(' ')
if oper == '+' :
pattern = getSPattern(str(num))
if pattern in pat:
pat[pattern] += 1
else:
pat[pattern] = 1
elif oper == '-' :
pattern = getSPattern(str(num))
pat[pattern] = max( pat[pattern] - 1, 0)
elif oper == '?' :
print pat.get(getPattern(num) , 0 )
我發現您的代碼有很多小問題,但無法說出它們是否會導致嚴重的性能問題:
您已經錯誤地設置並使用了defaultdict()
:
pat = defaultdict(str)
...
if pattern in pat:
pat[pattern] += 1
else:
pat[pattern] = 1
defaultdict()
構造函數的參數應該是值的類型,而不是鍵。 正確設置defaultdict后,您只需執行以下操作:
pat = defaultdict(int)
...
pat[pattern] += 1
因為如果模式不存在,該值現在默認為零。
由於規范說:
-ai-從多集中刪除一次出現的非負整數ai。 可以肯定的是,多集中至少有一個ai。
然后這樣:
pat[pattern] = max( pat[pattern] - 1, 0)
可以簡單地是這樣的:
pat[pattern] -= 1
您正在使用19個字符串,但是由於規范指出數字將小於10 ** 18,因此您可以改用18個字符串。
getSPattern()
執行zfill()
然后處理字符串,它應該以相反的順序執行,先處理字符串,然后zfill()
處理,因為不需要在前導零上運行邏輯。
我們不需要int()
的開銷即可將字符轉換為數字:
(int(news[i])%2 == 0)
考慮使用ord()
代替,因為數字的ASCII值與數字本身具有相同的奇偶校驗: ord('4')
-> 52
而且您不需要循環索引,只需循環字符即可。
以下是通過上述更改對代碼進行的重做,看看它是否仍然有效(!)並獲得任何性能:
from collections import defaultdict
def getPattern(string):
return string.zfill(18)
def getSPattern(string):
# pattern_list = (('0', '1')[ord(character) % 2] for character in string)
pattern_list = ('0' if ord(character) % 2 == 0 else '1' for character in string)
return ("".join(pattern_list)).zfill(18)
patterns = defaultdict(int) # holds keys as strings as and values as int
text = int(raw_input())
for _ in range(text):
operation, number = raw_input().strip().split()
if operation == '+':
pattern = getSPattern(number)
patterns[pattern] += 1
elif operation == '-':
pattern = getSPattern(number)
patterns[pattern] -= 1
elif operation == '?':
print patterns.get(getPattern(number), 0)
使用@cdlane已經完成的解釋,我只需要在我認為花費大量時間的地方添加對getSPattern
重寫getSPattern
。 根據我的初步評論,這可在https://eval.in/641639上獲得
def getSPattern(s):
patlist = ['0' if c in ['0', '2', '4', '6', '8'] else '1' for c in s]
return "".join(patlist).zfill(19)
使用zfill(18)可能會稍微節省您一些時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.