Skip to content Skip to sidebar Skip to footer

Passing A Non-iterable To List.extend ()

I am creating a public method to allow callers to write values to a device, call it write_vals() for example. Since these values will be typed live, I would like to simplify the us

Solution 1:

You can check if the passed parameter is a list with the isinstance() function.

An even better solution could be to support a variable number of arguments:

defwrite_to_device(*args):
   # |args| is now a list of all the arguments given to the function
   input_list.extend(args)

This way multiple values can be given to the function even without having to explicitly specify them as a list:

write_to_device(1)
write_to_device(1,2,3)

Solution 2:

You can use try...except...:

try:
    input_list = list(input_val)
except TypeError:
    input_list = list((input_val,))

This is pythonic.

P.S.: Variable parameters, as @sth proposes, is much better, but I leave this answer for completeness. Sometimes you cannot use variable parameters.

Solution 3:

Instead of checking the type, you could use try, except. Although, I'm curious to see how people better at python than I am would do this.

input_list = []
try:
    input_list.extend(input_val)
except TypeError:
    input_list.append(input_val)

This seems incomplete to me from an error-checking standpoint, but if you know users will only ever input a single value or a list, this will work.

Solution 4:

There are a few ways to do this, and which you choose depends on your needs.

You could try and convert the argument to a list, and assume if it doesn't work it should be interpreted as a single argument:

defwrite_to_device(args):
    try:
        args = list(args)
    except TypeError:
        args = [args]

    print args

This works pretty well, but you might run into problems if you pass a string as an argument:

>>> write_to_device(1)
[1]
>>> write_to_device([1,2])
[1, 2]
>>> write_to_device('abc')
['a', 'b', 'c']

You can correct for that by using isinstance to check if the argument is a string:

defwrite_to_device(args):
    ifisinstance(args, basestring):
        args = [args]
    else:
        try:
            args = list(args)
        except TypeError:
            args = [args]

    print args

Which gives you:

>>> write_to_device(1)
[1]
>>> write_to_device([1,2])
[1, 2]
>>> write_to_device('abc')
['abc']

As someone noted, you can allow your function to take an arbitrary number of arguments:

defwrite_to_device(*args):
    print args

Which gets you:

>>> write_to_device(1)
(1,)
>>> write_to_device([1,2])
([1, 2],)
>>> write_to_device('abc')
('abc',)
>>> write_to_device(*[1,2])
(1, 2)

My recommended way is just to require a list be passed to the function:

write_to_device([1])
write_to_device([1, 2, 3])

This is simple, straight-forward, and unambiguous.

Solution 5:

Based on what has gone before, I created this:

defadd2list(l,*args): l.extend(args)
# behaves like .extend, gets round issues of iterability     # so simple, so powerful!

Example:

answer = 42
mylist = []
add2list(mylist,1)
add2list(mylist,2,3,'a','b','c',answer)
print mylist

Result: [1, 2, 3, 'a', 'b', 'c', 42]

Post a Comment for "Passing A Non-iterable To List.extend ()"