我已经碰到过好几次了。我正在处理许多可以接受字符串列表的方法。有几次我意外地传递了一个字符串,它被拆分成一个列表,每个字符都被使用,这不是理想的行为。
def test(a,b):
x = []
x.extend(a)
x.extend(b)
return x
x = [1,2,3,4]
我不想发生什么:
test(x,'test')
[1, 2, 3, 4, 't', 'e', 's', 't']
我不得不采用一种奇怪的语法:
test(x,['list'])
我希望这些能够隐含地发挥作用:
test(x,'list')
[1, 2, 3, 4, 'test']
test(x,['one', 'two', 'three'])
[1, 2, 3, 4, 'one', 'two', 'three']
我真的觉得有一种“pythonic”方式可以做到这一点或涉及鸭子打字的事情,但我没有看到它。我知道我可以使用isinstance()检查它是否是一个字符串,但我觉得有更好的方法。
编辑:我正在使用python 2.4.3
答案 0 :(得分:10)
使用此
def test( x, *args ):
现在你可以做到
test( x, 'one' )
和
test( x, 'one', 'two' )
和
test( x, *['one', 'two',] )
答案 1 :(得分:9)
我很遗憾地说,但这确实是使用isinstance()
有意义的少数情况之一。然而,建议list
测试的其他答案之一是向后执行:str
(对于Python 2.x unicode
)是异常类型,因此那些是您测试的类型:
def test(a,b):
x = []
if isinstance(b, str): b = [b]
x.extend(a)
x.extend(b)
return x
或Python 2.x test isinstance(b, basestring)
。
答案 2 :(得分:2)
Explicit is better than implicit.
在我看来,你的第一个例子是明确的。它需要两个值并以易于理解的方式处理它们。虽然它对新的Python程序员来说“感觉”有些奇怪,但它的行为与预期的一样。 list.extend
接受列表,因此它将字符串视为字符列表。
您的提案将list.extend
的语义更改为等同于list.append
,但在处理字符串时仅 。对于那些想要你的函数将某个字符串视为字符列表并且必须像test(x,list('test'))
那样调用它的人来说,这将是一个真正的惊喜。
你可以做你想要的,但请不要。 : - )
答案 3 :(得分:1)
>>> def a(*args):
... x=[]
... for i in args:
... if '__iter__' in dir(i):
... x+=list(i)
... else:
... x.append(i)
... return x
...
>>> a(1,2,3,4)
[1, 2, 3, 4]
>>> a(1,2,[3,4])
[1, 2, 3, 4]
>>> a(1,2,[3,4],'123')
[1, 2, 3, 4, '123']
>>> a(1,2,[3,4],'123', 1231, (1, 2, 3, 4))
[1, 2, 3, 4, '123', 1231, 1, 2, 3, 4]
答案 4 :(得分:1)
对pod2metra的回答稍作调整,使该功能能够处理所有级别的煽动:
>>> def b(*args):
... x=[]
... for i in args:
... if '__iter__' in dir(i):
... x += b(*i)
... else:
... x.append(i)
... return x
...
>>> b(1, (2, (3, 4)))
[1, 2, 3, 4]
而不是功能' a'你有:
>>> a(1, (2, (3, 4)))
[1, 2, (3, 4)]
我知道这不是原始问题的意图,但也许这种概括可能有用。
答案 5 :(得分:0)
简单测试参数的类型:
def test(a,b):
x = a if isinstance(a, list) else [a]
x += b if isinstance(b, list) else [b]
return x