python - 如何迭代地改变函数参数而不是使用递归?
问题描述
我正在尝试细分三角形网格,直到每个边的长度小于任意值。我的方法很简单,我查看每条边并计算其长度。如果边的长度大于 100,我会细分包含该边的面。例如,我将共享一条边的一对面细分为 2 个面,然后更新顶点列表和面列表。但是,这仅处理大于 100 的第一条边。新形成的边可能与大于 100 的现有面共享边。我想检查所有这些边。我现在的猜测是,我可以递归或迭代地进行。我正在尝试以递归方式执行此操作,但我现在有一个我几乎无法理解并且不确定它是否返回正确结果的代码。这是我到目前为止在伪代码中所拥有的。
vertices= [[0.0, 0.0, 0.0], [0.0, 0.0, 50.0], [0.0, 50.0, 0.0], [0.0, 50.0, 50.0], [100.0, 0.0, 0.0], [100.0, 0.0, 50.0], [100.0, 50.0, 0.0], [100.0, 50.0, 50.0]]
faces = [[6, 7, 4], [4, 7, 5], [2, 6, 0], [0, 6, 4], [3, 2, 1], [1, 2, 0], [7, 3, 5], [5, 3, 1], [2, 3, 6], [6, 3, 7], [1, 0, 5], [5, 0, 4]]
edges = get_edges_from_faces(faces)
def subdivide_mesh(faces, vertices,edges):
for edge in edges:
if length(edge) > 100:
create_new_faces_and_update() #delete the face sharing this edge and update faces list
add_new_vertices() # add new vertices to
edges = get_edges_from_faces(faces)
subdivide_mesh(faces, vertices, edges)
解决方案
危险在于修改您当前正在迭代的列表。避免这种危险的最简单方法是制作列表的副本,这样您的输入列表(您正在迭代的列表)和您的输出列表(您正在修改的列表)不是同一个对象。
您在问题中提供的代码不是可重现的示例(例如,它缺少 的定义get_edges_from_faces
)。因此,我不会修复您的代码,而是解决一个类似但更简单的问题,您可以从中汲取灵感。
问题:x
在给定的数字列表中,将大于 10 的每个数字替换为总和为 的较小数字x
。例如,列表[3, 12, 5]
应该成为[3, 6, 6, 5]
或类似的东西。
我们将对一个列表进行迭代l
,并将其元素添加到结果列表中result
,并在必要时对其进行细分。
代码:
def subdivise_numbers(l):
result = []
for x in l:
if x < 10:
result.append(x)
else:
y = x // 2
z = x - y
result.append(y)
result.append(z)
return result
请注意我们从未向原始列表添加元素l
。
这回答了你的问题了吗?
请注意,如果列表最初包含大于 20 的数字y
,z
我们添加到结果中的 和可能仍然太大。解决此问题的一种可能方法是将我们的代码封装到带有停止条件的 while 循环中“如果我们在上次运行中没有细分任何内容,请停止”。这需要添加一个变量来跟踪您是否已经细分了当前运行。
def subdivise_numbers(l):
keep_going = True
result = l
while keep_going:
keep_going = False
l = result
result = []
for x in l:
if x < 10:
result.append(x)
else:
keep_going = True
y = x // 2
z = x - y
result.append(y)
result.append(z)
return result
另一种更好的方法是确保我们相加的数字y
已经z
小于 10:
def subdivise_numbers(l):
result = []
for x in l:
while x >= 10 and x > 0:
y = min(9, x // 2)
x = x - y
result.append(y)
result.append(x)
return result
推荐阅读
- jquery - 使用 jQuery 附加永久代码行
- arrays - 使用 Fortran IF 构造查找两个数组之间的匹配值
- android - 应用程序被杀死时的 FCM 通知
- sql - SQL 在创建数据库应用程序中的作用是什么
- python - 将 Python 作为 Windows 服务运行 - 使用模块调用另一个 Python 脚本
- php - mysql使用触发器更新另一个表
- ruby-on-rails - Ransack 中关联模型的访问属性
- c# - 使用依赖注入在工作线程中实例化对象
- arrays - 在 Swift 中对 2 个链接数组进行排序?
- java - 如何为原始 JSON + JSON(B) PostgreSQL 实现 Hibnernate 类型