Reputation: 862
Is there a way I can elegantly cast function inputs into a list? While ensuring that if the input is already a list, it is kept at a top level list?
For instance:
def pprint(input):
for i in input:
print(i)
a = ['Hey!']
pprint(a) # >>>>'Hey!'
b = 'Hey!'
pprint(b) # >>>> 'H', 'e', 'y', '!' # NOT WANTED BEHAVIOR
My current way around this is to do a type check, which is not very pythonic nor elegant. Is there a better solution?
# possible solution 1
def pprint2(input):
if type(input) not in [list, tuple]:
input = [input]
for i in input:
print(i)
# possible solution 2
# but I would really really like to keep the argument named! (because I have other named arguments in my actual function), but it does have the correct functionality!
def pprint3(*args):
for i in input:
print(i)
Upvotes: 3
Views: 6248
Reputation: 62
Make use of assert and isinstance
>>> inp = "String to test"
>>> try:
... assert not isinstance(inp, basestring)
... for i in inp:
... print i
... except AssertionError:
... print inp
...
String to test
Upvotes: -2
Reputation: 251186
Use isinstance
and collections.Iterable
:
from collections import Iterable
def my_print(inp):
#As suggested by @user2357112
if not isinstance(inp, Iterable) or isinstance(inp, basestring):
inp = [inp] #use just `str` in py3.x
for item in inp: #use `yield from inp` in py3.x
yield item
...
>>> for x in my_print('foo'):
... print x
...
foo
>>> for x in my_print(range(3)):
print x
...
0
1
2
>>> for x in my_print(dict.fromkeys('abcd')):
print x
...
a
c
b
d
Note that pprint
is name of standard module in python, so I'd suggest you to use a different variable name.
Upvotes: 4