将不可迭代的值传递给list.extend()

时间:2010-04-06 21:03:13

标签: python list

我正在创建一个公共方法,允许调用者将值写入设备,例如将其称为write_vals()。

由于这些值将被实时输入,我想通过允许他们输入列表或单个值来简化用户的生活,具体取决于他们需要写入多少值。例如:

write_to_device([1,2,3])

write_to_device(1)

我的功能想要使用平面列表,所以我试着变得聪明并编写类似这样的代码:

input_list = []  
input_list.extend( input_val )

当用户输入列表时,这可以顺利运行,但当用户输入单个整数时,它会失败:

TypeError:'int'对象不可迭代

使用list.append()会在传入列表时创建一个嵌套列表,这将是另一个平淡的麻烦。

检查传入的对象的类型似乎是笨拙和非pythonic,并希望list.extend()接受非迭代,这让我无处可去。所以尝试了各种其他编码方法。

建议(仅限编码相关)将不胜感激。

5 个答案:

答案 0 :(得分:8)

您可以检查传递的参数是否是包含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)

答案 1 :(得分:4)

您可以使用try...except...

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

这是pythonic。

P.S。:变量参数,如@sth proposes,要好得多,但我保留这个答案是为了完整性。有时你不能使用变量参数。

答案 2 :(得分:3)

除了检查类型,您可以使用try,除了。虽然,我很想知道人们在python上的表现会比我更好。

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

从错误检查的角度来看,这对我来说似乎不完整,但如果您知道用户只会输入单个值或列表,那么这将有效。

答案 3 :(得分:2)

有几种方法可以做到这一点,您选择的方法取决于您的需求。

您可以尝试将参数转换为列表,并假设它不起作用,它应该被解释为单个参数:

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']

您可以使用isinstance检查参数是否为字符串来纠正错误:

def write_to_device(args):
    if isinstance(args, basestring):
        args = [args]
    else:
        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')
['abc']  

正如有人指出的那样,你可以允许你的函数采用任意数量的参数:

def write_to_device(*args):
    print args

哪个可以帮到你:

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

我推荐的方法是要求将一个列表传递给函数:

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

这很简单,直截了当,而且毫不含糊。

答案 4 :(得分:0)

根据之前的情况,我创建了这个:

[
   {
      "command": "if",
      "conditionValueName": "foo",
      "conditionValueOperator": "equals",
      "conditionValueOperand": "bar",
      "then": {
         "command": "move",
         "axis": "x",
         "distance": 1
      },
      "else": {
         "command": "move",
         "axis": "y",
         "distance": 3
      }
   }
]

示例:

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

结果:[1,2,3,' a',''' c',42]