我有一个runquery调用函数,它调用数据库,然后逐个产生行.我写了一个memoize装饰器(或者更确切地说,我只是从这个stackoverflow问题中偷走了一个)但是在后续调用中它只产生一个空序列,大概是因为生成器的值只能产生一次.
我怎么能修改适用于Python生成器的memoization装饰器?我意识到我需要在某些时候将它存储在内存中,但我想在装饰器中处理它而不是修改原始函数.
memoization函数的当前代码是:
def memoized(f):
# Warning: Doesn't work if f yields values
cache={}
def ret(*args):
if args in cache:
return cache[args]
else:
answer=f(*args)
cache[args]=answer
return answer
return ret
Run Code Online (Sandbox Code Playgroud) 好吧,这是现实世界的场景:我正在编写一个应用程序,我有一个代表某种类型文件的类(在我的例子中,这是照片,但细节与问题无关).Photos类的每个实例对于照片的文件名应该是唯一的.
问题是,当用户告诉我的应用程序加载文件时,我需要能够识别文件何时已加载,并使用现有实例作为该文件名,而不是在同一文件名上创建重复实例.
对我而言,使用memoization似乎是一个很好的情况,并且有很多例子,但在这种情况下,我不只是记住一个普通的函数,我需要记忆__init__().这造成了一个问题,因为在__init__()被调用的时候已经太晚了,因为已经创建了一个新实例.
在我的研究中,我发现了Python的__new__()方法,我实际上能够编写一个简单的工作示例,但是当我尝试在我的真实世界对象上使用它时它就崩溃了,我不知道为什么(我唯一可以做到的)我想到的是我的真实世界对象是我无法控制的其他对象的子类,因此这种方法存在一些不兼容性.这就是我所拥有的:
class Flub(object):
instances = {}
def __new__(cls, flubid):
try:
self = Flub.instances[flubid]
except KeyError:
self = Flub.instances[flubid] = super(Flub, cls).__new__(cls)
print 'making a new one!'
self.flubid = flubid
print id(self)
return self
@staticmethod
def destroy_all():
for flub in Flub.instances.values():
print 'killing', flub
a = Flub('foo')
b = Flub('foo')
c = Flub('bar')
print a
print b
print c
print a is b, b is c
Flub.destroy_all()
Run Code Online (Sandbox Code Playgroud)
哪个输出:
making a new one! …Run Code Online (Sandbox Code Playgroud) 我正在努力理解Statemonad,并编写了著名的斐波那契数列的两个简单版本来记忆该函数。let体内的那只跑的很慢。那个<-跑得很快。我的问题:为什么?<-在允许M.lookup通孔Data.Map工作的同时,是否让以某种方式引起全面评估?
-- using state monad and let
-- very slow
fibLet :: Int -> State (M.Map Int Integer) Integer
fibLet n = do
case n of 0 -> return 0
1 -> return 1
n -> do
mp <- get
if M.member n mp
then return $ fromJust (M.lookup n mp)
else do
let s1 = evalState (fibLet (n - 1)) mp
let s2 = evalState (fibLet (n …Run Code Online (Sandbox Code Playgroud) 我有一个函数,它接受一个参数并产生一个结果.不幸的是,函数产生结果需要很长时间.使用相同的输入经常调用该函数,这就是为什么我可以方便地缓存结果.就像是
let cachedFunction = createCache slowFunction
in (cachedFunction 3.1) + (cachedFunction 4.2) + (cachedFunction 3.1)
Run Code Online (Sandbox Code Playgroud)
我正在研究Data.Array,虽然数组是懒惰的,但我需要用一对对象(使用listArray)初始化它 - 这是不切实际的.如果'key'是例如'Double'类型,我根本无法初始化它,即使理论上我可以为每个可能的输入分配一个Integer,我有几万个可能的输入,我实际上只使用了少数几个.我需要使用函数而不是列表初始化数组(或者,最好是哈希表,因为只使用少量的resutls).
更新:我正在阅读备忘录文章,据我所知,MemoTrie可以按我想要的方式工作.也许.有人可以尝试生成'cachedFunction'吗?对于一个需要2个Double参数的慢函数?或者,或者,在〜[0..1亿]的域中采用一个不会占用所有内存的Int参数?
每次调用一个函数时,如果给定的一组参数值的结果尚未被记忆,我想将结果放入内存表中.一列用于存储结果,另一列用于存储参数值.
我该如何最好地实现这一点?争论的种类繁多,包括一些枚举.
在C#中,我通常使用DataTable.Scala中有同等的东西吗?
我@functools.lru_cache在Python 3.3中使用.我想将缓存保存到文件中,以便在重新启动程序时恢复它.我该怎么办?
编辑1可能的解决方案:我们需要挑选任何类型的可调用
问题酸洗__closure__:
_pickle.PicklingError: Can't pickle <class 'cell'>: attribute lookup builtins.cell failed
Run Code Online (Sandbox Code Playgroud)
如果我尝试在没有它的情况下恢复功能,我会得到:
TypeError: arg 5 (closure) must be tuple
Run Code Online (Sandbox Code Playgroud) 我想编写一个函数once,接受回调作为输入并返回一个函数.当第一次调用返回的函数时,它应该调用回调并返回该输出.如果它被调用任何额外的时间,而不是再次调用回调,它将只是从第一次调用时返回输出值.
以下是我试图做的事情.但我没有按照我的预期得到结果.我需要理解这个概念.
function once(func) {
let num;
function retFunc(x){
num = func(x);
return num;
}
return retFunc;
}
function addByTwo(input){
return input + 2;
}
var onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
console.log(onceFunc(9001)); //should log 6
Run Code Online (Sandbox Code Playgroud) 我试图回答这个问题,只使用递归(动态编程) http://en.wikipedia.org/wiki/Longest_increasing_subsequence
从文章和SO周围,我意识到最有效的现有解决方案是O(nlgn).我的解决方案是O(N),我找不到它失败的情况.我包括我使用的单元测试用例.
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
public class LongestIncreasingSubseq {
public static void main(String[] args) {
int[] arr = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, 1};
getLongestSubSeq(arr);
}
public static List<Integer> getLongestSubSeq(int[] arr) {
List<Integer> indices = longestRecursive(arr, 0, arr.length-1);
List<Integer> result = new ArrayList<>();
for (Integer i : indices) {
result.add(arr[i]);
}
System.out.println(result.toString());
return result;
}
private static List<Integer> longestRecursive(int[] arr, …Run Code Online (Sandbox Code Playgroud) java algorithm memoization dynamic-programming time-complexity
我是Lisp的初学者.我正在尝试记忆递归函数来计算Collatz序列中的项数(对于Project Euler中的问题14 ).我的代码是:
(defun collatz-steps (n)
(if (= 1 n) 0
(if (evenp n)
(1+ (collatz-steps (/ n 2)))
(1+ (collatz-steps (1+ (* 3 n)))))))
(defun p14 ()
(defvar m-collatz-steps (memoize #'collatz-steps))
(let
((maxsteps (funcall m-collatz-steps 2))
(n 2)
(steps))
(loop for i from 1 to 1000000
do
(setq steps (funcall m-collatz-steps i))
(cond
((> steps maxsteps)
(setq maxsteps steps)
(setq n i))
(t ())))
n))
(defun memoize (fn)
(let ((cache (make-hash-table :test #'equal)))
#'(lambda (&rest …Run Code Online (Sandbox Code Playgroud) memoization ×10
haskell ×3
python ×3
caching ×2
monads ×2
algorithm ×1
common-lisp ×1
generator ×1
java ×1
javascript ×1
lisp ×1
python-3.x ×1
scala ×1
singleton ×1
state-monad ×1
unique ×1