Passing non-iterable to list.extend ()

I am creating an open method that allows callers to write values ​​to a device, such as its write_vals ().

Since these values ​​will be printed live, I would like to simplify the life of the user by allowing them to enter either a list or a single value, depending on how many values ​​they should write. For instance:

write_to_device([1,2,3])

or

write_to_device(1)

My function would like to work with a flat list, so I tried to be smart and code something like this:

input_list = []  
input_list.extend( input_val )

This works smoothly when the user enters a list, but fails when the user enters a single integer:

TypeError: object 'int' is not iterable

Using list.append () would create a nested list when the list was sent, which would be an additional obstacle to anti-aliasing.

, list.extend() non-iterables, . .

( , ) .

+3
5

try...except...:

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

pythonic.

P.S.: , @sth , , . .

+4

, isinstance().

:

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

, , :

write_to_device(1)
write_to_device(1,2,3)
+8

try, except. , , , , .

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

, , , .

+3

, , .

, , :

def write_to_device(args):
    try:
        args = list(args)
    except TypeError:
        args = [args]

    print args

, , :

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

You can fix this by using isinstanceto check if the argument is a string:

def write_to_device(args):
    if isinstance(args, basestring):
        args = [args]
    else:
        try:
            args = list(args)
        except TypeError:
            args = [args]

    print args

What gives you:

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

As someone noted, you can let your function accept an arbitrary number of arguments:

def write_to_device(*args):
    print args

What you need:

>>> 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 to simply require the list to be passed to the function:

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

It is simple, straightforward and unambiguous.

+2
source

Based on what was before, I created this:

def add2list(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]

0
source

Source: https://habr.com/ru/post/1740064/


All Articles