Python:类设计 - 列表转换(批评我的代码)
我一直在考虑一个对列表转换有用的类。 这是我当前的实现:
class ListTransform(object):
"""Specs: stores original list + transformations.
Transformations are stored in a list.
Every transformation is a func call, with
one parameter, transformations are done in place.
"""
def __init__(self, _list):
self.orig_list = _list
self.reset()
def addtransform(self,t):
self.transforms.append(t)
def reset(self, ts = []):
self.transforms = ts
def getresult(self):
li = self.orig_list[:] # start from a copy from the original
# call all the in-place transform functions in order
for transform in self.transforms:
transform(li)
return li
def pick_transform(pickindexes):
"""Only includes elements with specific indexes
"""
def pt(li):
newli = []
for idx in pickindexes:
newli.append(li[idx])
del li[:] # clear all the elements
li.extend(newli)
return pt
def map_transform(fn_for_every_element):
"""Creates a transformation, which will call a specific
function for every element in a list
"""
def mt(li):
newli = map(fn_for_every_element, li)
del li[:] # clear
li.extend(newli)
return mt
# example:
# the object which stores the original list and the transformations
li = ListTransform([0,10,20,30,40,50,60,70,80,90])
# transformations
li.addtransform(map_transform(lambda x: x + (x/10)))
li.addtransform(pick_transform([5,6,7]))
# getting result, prints 55, 66, 77
print li.getresult()
效果很好,但是,以不标准的方式实现某些东西的感觉让我感到困扰。
在此实现中您会使用哪些我没有使用过的 Python 功能?您将如何改进本课程背后的整体设计/想法?您将如何改进代码?
此外,因为重新发明轮子感觉很尴尬:替换此类的标准工具是什么?
谢谢。
I have been thinking about a class which could be useful for list transformations.
Here is my current implementation:
class ListTransform(object):
"""Specs: stores original list + transformations.
Transformations are stored in a list.
Every transformation is a func call, with
one parameter, transformations are done in place.
"""
def __init__(self, _list):
self.orig_list = _list
self.reset()
def addtransform(self,t):
self.transforms.append(t)
def reset(self, ts = []):
self.transforms = ts
def getresult(self):
li = self.orig_list[:] # start from a copy from the original
# call all the in-place transform functions in order
for transform in self.transforms:
transform(li)
return li
def pick_transform(pickindexes):
"""Only includes elements with specific indexes
"""
def pt(li):
newli = []
for idx in pickindexes:
newli.append(li[idx])
del li[:] # clear all the elements
li.extend(newli)
return pt
def map_transform(fn_for_every_element):
"""Creates a transformation, which will call a specific
function for every element in a list
"""
def mt(li):
newli = map(fn_for_every_element, li)
del li[:] # clear
li.extend(newli)
return mt
# example:
# the object which stores the original list and the transformations
li = ListTransform([0,10,20,30,40,50,60,70,80,90])
# transformations
li.addtransform(map_transform(lambda x: x + (x/10)))
li.addtransform(pick_transform([5,6,7]))
# getting result, prints 55, 66, 77
print li.getresult()
This works well, however, the feeling of implementing something in a substandard manner bothers me.
What Python features would you use in this implementation, I haven't used? How would you improve the overall design/ideas behind this class? How would you improve the code?
Also, since reinventing the wheel feels awkward: what are the standard tools replacing this class?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
考虑到一般范围而不是特定用例,我会以更“功能”的方式来看待这个问题:
不要进行适当的转换——而是返回新列表。这就是函数式编程中标准函数的工作原理(还有 Python 中的
map()
、filter()
和reduce()
)。专注于转换而不是数据。特别是,我根本不会创建像
ListTransform
这样的类,而只会创建某种可以链接的转换对象。为了在考虑函数式编程的情况下进行编码,转换将只是函数,就像在您的设计中一样。您所需要的只是变换的某种组合:(
为了简单起见,给定的实现只有两个参数,而不是任意数量。)您的示例现在非常简单:
另一种方法是实现转换为类而不是函数。
Having a general scope and not a particular use case in mind, I would look at this in a more "functional" way:
Don't make the tranformations in place -- rather return new lists. This is how standard functions in functional programming work (and also
map()
,filter()
andreduce()
in Python).Concentrate on the transformations rather than on the data. In particular, I would not create a class like your
ListTransform
at all, but rather only have some kind of transformation objects that can be chained.To code this having functional programming in mind, the transforms would simply be functions, just like in your design. All you would need in addition is some kind of composition for the transforms:
(For the sake of simplicity the given implementation has only two parameters instead of an arbitrary number.) Your example would now be very simple:
An alternative would be to implement the transforms as classes instead of functions.
不要使用空列表作为默认参数。使用 None 并对其进行测试:
我是一个众所周知的 Python 初学者陷阱。
Do not use an empty list as default argument. Use None and test for it:
I's a well known Python's beginner pitfall.
您可以扩展
list
类本身,并在需要元素时延迟应用转换。这是一个简短的实现 - 它不允许对转换进行索引操作,但您可以在堆栈中应用任何映射转换。现在您已经准备好了:
好的 - 我可能在 getitem 方法中使用“reduce”调用过度了 - 但这是有趣的部分。 :-)
请随意将其重写为更多行以提高可读性:
如果您喜欢这个想法,您可以包含一个“filter”成员来为项目创建过滤函数,并检查转换上的参数数量以允许它们与索引一起使用,甚至到达其他列表项。
You could extend the
list
class itself, and apply the transforms lazily as the elements are needed. Here is a short implementation - it does not allow for index manipulation on the transforms, but you can apply any mapping transform in a stack.And you are ready to go:
Ok - I may have overreached with the "reduce" call in the getitem method - but that is the fun part. :-)
Feel free to rewrite it in more lines for readability:
If you like the idea, you could include a "filter" member to create filtering functions for the items, and check for the number of parameters on the transforms to allow them to work with indexes, and even reach other list items.