
代码如下, 为什么 get_a 没有返回默认?
In [7]: a = [{'a':1},{'a':2}] In [8]: a Out[8]: [{'a': 1, 'b':'夏天'}, {'a': 2, 'b':'冬天'}] In [9]: def filter_a(k,v): ...: return filter(lambda x: x[k] == v, a) ...: In [10]: def get_a(k,v): ...: return next(filter_a(k,v), get_a('a',2)) # 我的想法是如果 iter 为空, 返回 这个默认 ...: In [11]: get_a('a',1) 报错如下
--------------------------------------------------------------------------- RecursionError Traceback (most recent call last) <ipython-input-11-428f62971dec> in <module> ----> 1 get_a('a',1) <ipython-input-10-a36c60ef3685> in get_a(k, v) 1 def get_a(k,v): ----> 2 return next(filter_a(k,v), get_a('a',2)) 3 ... last 1 frames repeated, from the frame below ... <ipython-input-10-a36c60ef3685> in get_a(k, v) 1 def get_a(k,v): ----> 2 return next(filter_a(k,v), get_a('a',2)) 3 RecursionError: maximum recursion depth exceeded while calling a Python object 1 nook4sh 2021 年 9 月 16 日 因为你的递归没有终止条件,改成 return next(filter_a(k,v), {'a', 2}) |
3 hsfzxjy 2021 年 9 月 16 日 via Android 参数会先于函数调用求值,所以不管 iter 是不是空 return next(filter_a(k,v), get_a('a',2)) 里的 get_a('a', 2) 都会执行 |
5 plko345 OP @hsfzxjy 可是像这样却没有问题 ```py In [13]: def get_b(x): ...: return x[0] ...: In [14]: next(filter(lambda x: x==0, [0,1,2]), get_b('bc')) Out[14]: 0 ``` |
6 plko345 OP |
7 princelai 2021 年 9 月 16 日 def get_a(k,v): return next(filter_a(k,v), next(filter_a('a',2))) 这样呢 |
8 2i2Re2PLMaDnghL 2021 年 9 月 16 日 你在 get_a 里面还没进迭代器呢就先重复 get_a 了,罚您重看 SICP 1.1.5 next 的参数不会懒惰求值,咱把 get_a 写成 applicative order def get_a(k,v): t1 = filter_a(k,v) t2 = get_a('a',2) t3 = next(t1, t2) return t3 显然,计算 t2 的时候就已经无限递归了 你需要的大概是 try: return next(filter_a(k,v)) except StopIteration: return get('a',2) 或者 chain 一个生成器上去 next(itertools.chain(filter_a(k,v), (get_a('a',2) for _ in range(1)))) 但也有个问题,如果没有 x['a']==2 的记录,还是会无限递归。 |
9 2i2Re2PLMaDnghL 2021 年 9 月 16 日 #4 不是返回 default,而是先求 default 再求 next 但因为求 default 导致了无限递归,你永远不会求 next 不妨试试这样写 original_next = next def next(*args): ... print("running next()") ... return original_next(*args) 你再试试,你会发现 "running next()" 一次也没被打印。 |
10 plko345 OP |
11 plko345 OP 我还是乖乖返回 None 再做次判断吧 |