Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 迭代期间与列表/元组和字符串不同_Python - Fatal编程技术网

Python 迭代期间与列表/元组和字符串不同

Python 迭代期间与列表/元组和字符串不同,python,Python,是编写接受参数的函数的常用模式,如果参数是标量(如数字或字符串),则对其应用某些操作;如果参数是iterable,则对该iterable的每个元素应用相同的操作 问题是字符串是可编辑的,所以我不能依靠请求原谅而不是请求许可来实现这一点,因为iter('hello world')不会引发TypeError 比如说 def应用(func,val): 尝试: 对于iter中的v(val): 打印(函数(v),结束=“”) 打印() 除类型错误外: 打印(函数(val)) 应用(λx:x+1,1)#2。

是编写接受参数的函数的常用模式,如果参数是标量(如数字或字符串),则对其应用某些操作;如果参数是iterable,则对该iterable的每个元素应用相同的操作

问题是字符串是可编辑的,所以我不能依靠请求原谅而不是请求许可来实现这一点,因为
iter('hello world')
不会引发TypeError

比如说

def应用(func,val):
尝试:
对于iter中的v(val):
打印(函数(v),结束=“”)
打印()
除类型错误外:
打印(函数(val))
应用(λx:x+1,1)#2。。。好啊
应用(λx:x*2,范围(3))0 2 4。。。好啊
应用(str.upper,['hello','world'])#hello world。。。可以
应用(str.upper,'hello world')#L L O W O R L D。。。哎呀
我可以要求授权。但这只适用于字符串的子类型

def apply_safe(func,val):
如果issubclass(类型(val),str):
打印(函数(val))
返回
尝试:
对于iter中的v(val):
打印(函数(v),结束=“”)
打印()
除类型错误外:
打印(函数(val))
另一个选项是将此逻辑添加到类型中,这似乎是正确的方法,因为iterable是字符串的不希望的行为(在本例中)。但是对于调用者来说,这很容易出错,很快或很晚它就会忘记使用
NonIterableString
或任何其他类调用它

类非可iterablestring(str):
定义(自我):
raise TypeError()
应用(str.upper,NonIterableString('hello world'))#hello world
我发现的最后一个解决方案是这个,它解决了我的问题,但可能不适用于现有代码

def apply_multi(func,*vals):
对于VAL中的v:
打印(函数(v),结束=“”)
打印()
这似乎是更惯用的一个。它总是有效的,小巧优雅,但因为它不面对问题,它巧妙地避开了它。这里的问题是,我需要为每种情况编写一个这样的函数,这似乎不是一个坏主意,但仍然很冗长

最后,这里是完整的示例

def应用(func,val):
尝试:
对于iter中的v(val):
打印(函数(v),结束=“”)
打印()
除类型错误外:
打印(函数(val))
def应用_安全(func,val):
如果(issubclass(类型(val),str)):
打印(函数(val))
返回
尝试:
对于iter中的v(val):
打印(函数(v),结束=“”)
打印()
除类型错误外:
打印(函数(val))
def应用(函数,*VAL):
对于VAL中的v:
打印(函数(v),结束=“”)
打印()
类别非ITERABLESTRING(str):
定义(自我):
raise TypeError()
应用(λx:x+1,1)#2=>ok
应用(λx:x*2,范围(3))#0 2 4=>ok
应用(str.upper,['hello','world'])#hello world=>ok
应用(str.upper,'hello world')#he L O W O R L D=>oops
应用(str.upper,NonIterableString('hello world'))#hello world=>ok
应用_safe(str.upper,'Hello world')35; Hello world=>j
应用_multi(str.upper,‘hello world’)35; hello world=>ok

最后,我的问题是,在python中有没有像标量类型而不是iterable类型那样处理字符串的AFFNFP方法?

我认为一个好的解决方案是这样的:

默认值={
str:错
}
def应用(func、val、isiter:bool=None):
如果isiter为“无”:
isiter=默认值[类型(val)],如果默认值中的类型(val)为True
如果访客:
尝试:
对于国际热核实验堆(val)中的i:
打印(功能(i),结束=“”)
打印()
除类型错误外:
打印(函数(val))
其他:
打印(函数(val))
此方法允许您决定(仅当值为iterable时)是否将该值视为iterable。如果您希望此行为具有字符串类型,可能有一天您会将函数应用于列表,但只应用于列表本身,而不会将函数应用于每个值

此处
defaults
表示默认情况下是否应将iterable类型视为iterable,在这种情况下,
str
默认情况下不应视为iterable

如果需要,您还可以使用一个参数来覆盖此“默认”行为(但只有在合理的情况下)。例如:

应用(λx:x+1,1)#2。。。好啊 应用(λx:x*2,范围(3))0 2 4。。。好啊 应用(str.upper,['hello','world'])#hello world。。。可以 直到这里一切都是一样的,一切都按预期运行。那么让我们看看:

apply(str.upper,'hello world')#hello world。。。可以
应用(str.upper,'hello world',isiter=True)#L L O W O R L D。。。可以
正如您所见,hello world最初被视为一个值,就像我们在
默认值中定义的那样,如果我们设置
isiter=True
,那么它将被视为您设置的值

让我们看另一个例子:

apply(lambda x:2*x,['hello','world')#hellohello world。。。可以
应用(lambda x:2*x,['hello',world',isiter=False)#['hello','world','hello','world']。。。可以
如您所见,在第一种情况下,列表被视为一个iterable,如果我们设置
isiter=False
函数,它将应用于列表本身

最后,让我们看看是否尝试将不可iterable类型视为可iterable:

apply(lambda x:x+1,1,isiter=True)2。。。好啊
在这种情况下,
try:except:
处理错误


字典非常方便,因为设置默认行为将确保您在大多数情况下都必须使用isiter

apply\u multi
是最佳选择。为什么猜测?打电话的人知道他们是有一件事还是有许多事。如果没有,可能是
?@NedBatchelder不会离开。他可能在作曲,并试图保持同样的行为