我正在尝试创建一个泛型函数,该函数以数据结构作为输入,然后将每个非空项(例如: str、int)单独发送:
def print_this(v, delim1="", delim2=""):
print v, delim1, delim2
def pass_many(vals, some_funct, args=None):
if vals:
if type(vals) == list or type(vals) == tuple:
for v in vals:
if v:
pass_many(v, some_funct, args)
else:
if args:
some_funct(vals, *args)
else:
some_funct(vals)
>>> pass_many([['foo'],['',(5,3)]], print_this, ["newline","notnewline"])
foo newline notnewline
5 newline notnewline
3 newline notnewline我现在的实现还不错,但感觉很烦躁.
我怎么能把它概括成展开所有的数据结构(除了字符串),使它不那么烦琐?
发布于 2012-06-09 21:52:36
我会做些改变:
1)将内部循环中的if v签出放入函数体(if not vals: return) --这样看起来更一致,除非您希望pass_many(0,print)打印一些东西,但pass_may([0], print)不打印?
2)我不确定是否有理由使用args=None,然后检查它是否是None,而不是一开始就做args=(),这样实现就更短了。
3)肯定有更好的方法来检查某物是否是元组/列表/集/等等,而不是使用类型。不幸的是没有一个是完美的..。我真希望有一个很好的干净的方法来区分这些东西与字符串和字典。
也许他是我能想到的最一般的东西,使用来自抽象基类的集合模块 -它涵盖了可迭代对象的所有元素,除了映射(字典等)--除非您想包含这些元素?)字符串(我认为基本字符串类型/S在python3中可能有所不同?)不确定。)
from collections import Iterable, Mapping
def pass_many(vals, some_funct, args=()):
if not vals:
return
if isinstance(vals, Iterable) and not isinstance(vals, (basestring, Mapping)):
for v in vals:
pass_many(v, some_funct, args)
else:
some_funct(vals, *args)不过,ABC并不完美--也许使用hasattr检查某些东西是可迭代的还是映射更好。不确定。也许每一种可能的方式都会有一些不利的一面。
如果您想变得更严格,只接受普通列表和元组,而不接受其他可迭代性,那么isinstance(vals, (list, tuple))就可以了。它只是在迭代器之类的东西上不起作用--这是否重要取决于预期的用途。
https://codereview.stackexchange.com/questions/12414
复制相似问题