- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我注意到当我在列表理解中使用递归时会发生一些奇怪的事情。如果递归太深,解释器似乎会空闲(我等了 5 分钟,但什么也没发生)。
为了这个问题,假设我想展平嵌套列表(我不想 - 但这是一个说明我遇到的问题的简短代码示例):
def flatten(x):
if isinstance(x, list):
return [a for i in x for a in flatten(i)]
else:
return [x]
使用辅助函数创建嵌套列表:
def wrap_in_lists(value, depth):
a = value
for _ in range(depth):
a = [a]
return a
它在使用时效果很好:
>>> flatten(wrap_in_lists(1, 2**10))
[1]
但是当我使用时它完全停止了:
>>> flatten(wrap_in_lists(1, 2**11))
# Nothing happens, no exception, no result, no segfault, ...
奇怪的是,使用生成器的类似方法并没有表现出这种行为:
def flatten(l):
def inner(x):
for item in x:
if isinstance(item, list):
yield from inner(item)
else:
yield item
return list(inner(l))
>>> flatten(wrap_in_lists(1, 2**11))
[1]
>>> # although increasing the depth leads to an recursion error
>>> flatten(wrap_in_lists(1, 2**12))
RecursionError: maximum recursion depth exceeded
如果这很重要,我会在 jupyter 实验室的 Windows 上使用 Python 64 位 3.6.6。
最佳答案
这是一个简单的 StackOverflow,发生在 达到递归限制之前。
在第二种(生成器)方法中,它达到了深度为 2**12
的递归限制.这意味着 2**11
应该在第一种方法中达到递归限制。那是因为列表推导式创建了一个额外的堆栈框架,因此它的堆栈框架是生成器解决方案的两倍。它没有抛出 RecursionError 的事实意味着解释器发生了“致命”的事情(或者某处存在无限循环)。
但这不是无限循环,因为如果您检查 jupyter 实验室响应(例如,如果您从命令行使用 jupyter lab
启动它),您会注意到在运行 flatten(wrap_in_lists(1, 2**11))
后不久行它会打印一个 kernel <xyz> restarted
.所以没有响应是不正确的,内核刚刚崩溃并且 [*]
在这种情况下显示在 jupyter lab 单元格中仅表示计算未完成(因为崩溃)。
如果您更改 Python 的递归限制或使用为您更改它的解释器,这就是为什么您要非常小心的原因之一。
关于python - 当递归非常深入时,理解中的递归调用有什么特别之处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51337082/
拿这个: var lists:{ item1:{} ,item2:{} ,item3:{} ,item4:{} } 由于它基本上是空的,我想要一个函数(可能但不一定是 _lodash
我想更改 ng bootstrap 分页组件的样式并在 Angular 6 应用程序中使用 /deep/ 链接。以下代码工作正常,但控制台显示警告,指出该代码已被弃用。 那么,我应该如何更改它以消除警
使用 webcomponents,您可以使用 /deep/ 定位 shadowdom 的内部元素,在我尝试使用事件委托(delegate)之前它工作正常。 一个常规的点击功能将起作用: $('html
在 Swift 中,我试图实现一个单词 Trie,使用文字表示作为一系列嵌套的 NSObject。这是 Trie。 let GEENITRIE:NSObject = [ "i":[
运行 npm update 更新 package.json 中列出的项目;但是,这些项目的依赖关系仍然过时。 明显的解决方法是再次运行 npm update。有时我需要运行它 3 次以上才能使 npm
我创建了 2 级嵌套 linq 查询: var data = (from p in Departments join e in Employees on p.Id equals
首先是代码 #include typedef wchar_t* BSTR; wchar_t hello[] = L"Hello"; class _bstr_t { public: opera
我要编写一个 lisp 程序来生成十六进制数的实际值。我已经编写了一个函数,但似乎出现了 stackoverflow(深度)错误。我想知道是否有人可以指出我的错误或指导我朝着正确的方向前进。 如果没有
我想将每种类型都转换为boolean 或object type CastDeep = { [P in keyof T]: K extends K[] ? K[] : T[P] ex
我刚刚发现自己在写这个: fn init_timestamps(dir: &PathBuf, file_timestamps: &'static HashMap) { match fs::re
我有一个现有的 pybind11::array_t,需要进行复制构造。 pybind11 中是否有一个函数允许我对 array_t 进行深度复制? 我知道我可以创建一个新的 array_t,适当调整大
引用http://www.devx.com/tips/Tip/13291 ,它说我可以使用 memcpy 来复制由 sizeof() 确定的大小,但是,数组不是指向指针吗? 除了遍历数组,如何使用 m
我有多个成员(member),每个成员(member)都有一条记录,其中包含几个备注字段: Member ID Entry A Entry B 1 [memo t
$watchCollection 是否能够忽略对以 $ 开头的属性的更改?使用深度 $watch 时已经存在此行为,因为它依赖于 angular.equals 进行比较。 理想情况下,$watchCo
我有一个带有复杂键的 map - 例如,二维数组: m := make(map[[2][3]int]int) 当我在映射中插入一个新键时,Go 是否会对该键进行深度复制? a := [2][3]int
我需要查询如下所述的三个表。我了解简单的 JOIN,但是这个有点超出我的水平。 courses 有两列 id (PK) 和 courseTitle(示例 id 1,courseTitle 物理) cl
我有一个对象,它是 Realm 的 Object 子类,并且符合 Codable 以便在与 API 对话时与 JSON 相互转换。 如何利用 Codable 协议(protocol)进行深度复制(包括
我是一名优秀的程序员,十分优秀!