user1639926
user1639926

Reputation: 862

Python force input to be a list

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

Answers (2)

Mohit Bagga
Mohit Bagga

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

Ashwini Chaudhary
Ashwini Chaudhary

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

Related Questions