英文:
Is there a way to use "static" variables in a function to return values later on?
问题
我有以下输入:
[['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '10', '10', '10', '10', '10', '0', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0', '0', '10', '10', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0', '0', '10', '10', '0', '0'],
['0', '0', '10', '10', '10', '10', '10', '10', '0', '0', '0', '0', '10', '10', '10', '10', '0', '0', '0'],
['0', '0', '0', '10', '10', '10', '10', '10', '0', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '10', '10', '0', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '10', '10', '0', '0', '0', '10', '10', '10', '10', '10', '10', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']]
对于以下函数:
def assign_points(lists):
"""
Assigns points from a list of lists to Vec4 objects.
...
"""
z_max = float('-inf')
z_min = float('inf')
points = []
for y, l in enumerate(lists):
for x, point in enumerate(l):
try:
z, color = parse_point(point)
if color is None:
color = no_color(z)
points.append(Vec4(x, y, z, 0, color))
# Update z_max and z_min if necessary
if z > z_max:
z_max = z
if z < z_min:
z_min = z
except MyWarning as e:
exit(f"Error on line {str(y)}, item {str(x)}: {e}")
return points, z_max, z_min
然而,我的问题是:
- 我觉得
assign_points
函数太臃肿了,做了太多的事情并返回了太多的结果。 - 输入的列表可能会很大,我认为多次循环遍历它们是浪费的。
- 我不确定全局变量是否是最佳实践。
我考虑过编写一个函数来存储这些值,并且(根据作为参数的标志)在assign_points
之外调用时返回最大值。但我很确定Python没有静态变量(对吗?)
你会如何解决这个问题?我应该保持现状,还是使用全局变量,或者采取第三种选择?
英文:
I have the following input:
[['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '10', '10', '10', '10', '10', '0', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0', '0', '10', '10', '0', '0'],
['0', '0', '10', '10', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0', '0', '10', '10', '0', '0'],
['0', '0', '10', '10', '10', '10', '10', '10', '0', '0', '0', '0', '10', '10', '10', '10', '0', '0', '0'],
['0', '0', '0', '10', '10', '10', '10', '10', '0', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '10', '10', '0', '0', '0', '10', '10', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '10', '10', '0', '0', '0', '10', '10', '10', '10', '10', '10', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']]
For the following function:
def assign_points(lists):
"""
Assigns points from a list of lists to Vec4 objects.
...
"""
z_max = float('-inf')
z_min = float('inf')
points = []
for y, l in enumerate(lists):
for x, point in enumerate(l):
try:
z, color = parse_point(point)
if color is None:
color = no_color(z)
points.append(Vec4(x, y, z, 0, color))
# Update z_max and z_min if necessary
if z > z_max:
z_max = z
if z < z_min:
z_min = z
except MyWarning as e:
exit(f"Error on line {str(y)}, item {str(x)}: {e}")
return points, z_max, z_min
However
My problem is that:
- I feel
assign_points
is too bloated and does/returns too much. - the input lists can get quite big and I think looping trough them more than once is wasteful
- I'm not sure global vars is best practice
I thought about doing a function that stored the values and (depending on a flag as argument) returned the maximum values once called outside assign_points
. But I'm pretty sure python doesn't have static vars (right?)
How would you go about this problem? Should I leave it as is or make global vars or do a 3rd option?
答案1
得分: 1
如评论中建议的那样,定义自己的类将允许您实例化和操作对象以满足您的需求。
由于似乎有三个相关的值(points
、z_max
和z_min
),您可以让您的类继承自namedtuple
。然后,assign_points
可以作为您的类的方法创建:
from collections import namedtuple
class Vec4Obj(namedtuple('Vec4Obj', ['points', 'z_max', 'z_min'])):
def __new__(cls):
return super().__new__(cls, [], float('-inf'), float('inf'))
def assign_points(self, lists: list):
for y, l in enumerate(lists):
for x, point in enumerate(l):
try:
z, color = parse_point(point)
if color is None:
color = no_color(z)
self.points.append(Vec4(x, y, z, 0, color))
# 如果需要,更新 z_max 和 z_min
if z > self.z_max:
self.z_max = z
if z < self.z_min:
self.z_min = z
except Warning as e:
exit(f"第 {str(y)} 行,第 {str(x)} 项出错:{e}")
您可以定义其他方法。例如,可以编写一个只接受一个列表和一个 y
值的方法,以避免循环遍历所有列表,从而一次添加较少的点。
使用您的类将如下所示:
my_obj = Vec4Obj() # 实例化,初始值为 Vec4Obj(points=[], z_max=-inf, z_min=inf)
my_obj.assign_points(lists) # 将点添加到 my_obj.points,并设置 my_obj.z_min 和 my_obj.z_max
英文:
As suggested in the comments, defining your own class would allow you to instantiate and manipulate objects to your liking.
Since there seem to be three relevant values (points
, z_max
and z_min
) you could let your class inherit from namedtuple
. assign_points
can then be created as a method of your class:
from collections import namedtuple
class Vec4Obj(namedtuple('Vec4Obj', ['points', 'z_max', 'z_min'])):
def __new__(cls):
return super().__new__(cls, [], float('-inf'), float('inf'))
def assign_points(self, lists: list):
for y, l in enumerate(lists):
for x, point in enumerate(l):
try:
z, color = parse_point(point)
if color is None:
color = no_color(z)
self.points.append(Vec4(x, y, z, 0, color))
# Update z_max and z_min if necessary
if z > self.z_max:
self.z_max = z
if z < self.z_min:
self.z_min = z
except Warning as e:
exit(f"Error on line {str(y)}, item {str(x)}: {e}")
You can define other methods. For instance one that would take only one list and a y
value to avoid looping over all lists, hence adding fewer points at once.
Using your class would look like:
my_obj = Vec4Obj() # instantiate with value Vec4Obj(points=[], z_max=-inf, z_min=inf)
my_obj.assign_points(lists) # add points to my_obj.points and set my_obj.z_min and my_obj.z_max
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论