我正在嘗試學習如何提高代碼的速度。這個函式應該讀取一個非常長的字串,它似乎有點慢。輸入是一個字串,它應該被讀取并根據它所放置的“級別”回傳一個串列。我想知道是否有辦法提高以下代碼的速度:
def readexpr1(q): # q=[[16,[[4,4],4]],[[32,[4,16]],64]]```
y = []
lvl = 0
s = ""
for n in q:
# print(y, "-")
if n == "[":
lvl = 1
if s:
y.append(int(s)*(2**(lvl)))
s = ""
elif n == "]":
lvl -= 1
if s:
y.append(int(s)*(2**(lvl)))
s = ""
elif n == ",":
if s:
y.append(int(s)*(2**(lvl)))
s = ""
else:
s = "".join([s, n])
return y```
uj5u.com熱心網友回復:
只要每個值必須通過相乘2**L其中L是嵌套級,下面的代碼進行所需的轉化。
import ast
def collect(l, level):
"""Collect multiplied values from a list at `level`."""
for x in l:
if type(x) == list:
yield from collect(x, level 1)
else:
yield x * 2**level
def readexpr2(q):
"""Convert string to the list of multiplied values."""
s = ast.literal_eval(q)
return list(collect(s, 1))
print(readexpr2("[[16,[[4,4],4]],[[32,[4,16]],64]]"))
# Gives [64, 64, 64, 32, 256, 64, 256, 256]
uj5u.com熱心網友回復:
我完全相信dlask的解決方案是這里的正確解決方案,但是,在考慮這個問題時,我想到了一個有趣的想法,我想分享一下。
警告:這種方法絕對是 hackier,并且存在巨大的安全問題 -eval()可以并且會運行您放入其中的任何函式,因此如果您的輸入串列包含實際上是合法 Python 代碼的惡意值,它也會運行這些值。這就是為什么 dlask 的解決方案使用的原因ast.literal_eval()- 它不執行函式,并且不受此安全問題的影響。
撇開免責宣告,讓我們來看看代碼:
def double(nums):
return (2*x for x in nums)
def read_expr(expr):
code = "[" text.replace("]", "])").replace("[", "*double([") "]"
return eval(code)
如您所見,它確實有效:
>>> expr = "[[16,[[4,4],4]],[[32,[4,16]],64]]"
>>> read_expr(expr)
[64, 64, 64, 32, 256, 64, 256, 256]
現在怎么了?對于每個串列,它用[4, 16]文本替換該串列,例如,*double([4, 16])這意味著它呼叫double()我們的串列(將每個元素加倍),然后將其解包到封閉串列中(展平嵌套串列)。對于每個串列(包括最外面的串列)都會發生這種情況,這就是為什么我必須在末尾顯式地用[和包圍運算式]。
同樣,這并不是一個好的解決方案,您應該將其復制/粘貼到生產環境中。它展示了另一種查看同一問題的方法,使用一些巧妙的技巧來減少作業量。實際使用請使用dlask的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/377310.html
上一篇:我怎樣才能簡化這個?
