【问题标题】:Python list() function update to accept a non-iterable?Python list() 函数更新以接受不可迭代?
【发布时间】:2018-03-09 17:09:10
【问题描述】:

我一直在从事一个“学习项目”,其中涉及几个简短的单参数函数,其中参数可能是数字类型或数字列表。例如,

def magnitude_of(v):
    try:
        return math.sqrt(sum([vi**2 for vi in v]))
    except:
        return abs(v)

这当然是必要的,因为如果我这样做:

def magnitude_of(v):
    return math.sqrt(sum([vi**2 for vi in list(v)]))

...代码会失败,因为list() 只接受一个可迭代对象作为参数。

我的问题是:PSW 有没有考虑过让list() 处理任何论点?如果是这样,是什么阻止了更改的实施?

【问题讨论】:

  • 这似乎是一种可以实现的东西,但一直没有实现,因为没有足够的人要求它。我期待你的草根运动;-)
  • v 到底是什么?在第一个代码示例中,您正在迭代 v,这使得 v 看起来是可迭代的。但是,在下一个代码示例中,您说您不能使用 list(v),因为 v 不是可迭代的。
  • 可以在传递给列表理解之前将其包装到列表中。在某些情况下,显式优于隐式 =)
  • 您似乎将两个完全不相关的功能塞进了同一个功能中。为什么不写两个独立的函数,这样你就不用担心v 是什么了。
  • 虽然我通常支持试图对调用者友好的函数,但当函数需要可迭代时,处理单个值就像在调用函数时用 [...] 包装它一样简单。消除这两个击键并没有太大的价值。尤其是在这个函数中,结果是一样的。如果您想简化单项案例,您仍然可以通过检查可迭代的长度并在这种情况下返回 abs(v[0]) 来做到这一点。 (另外,您可以将vi**2 替换为vi*vi,这在我的机器上大约快十倍......)

标签: python language-design


【解决方案1】:

我会创建自己的列表函数并将其用于此特定目的。

例如:

def mlist(v):
    try:
        return list(v)
    except(TypeError):
        return [v]

现在你使用mlist 代替list

l1 = mlist(1)
l2 = mlist([1])

两者都会给出[1] 作为结果

【讨论】:

  • 我变了。我喜欢为调试目的分配一个变量。但在这种情况下,它并不是真的必要。
  • 实际上并没有回答我提出的问题,但我很擅长 DIY 方法来解决语言的一个小限制。
  • 如果您实际上不需要列表,但只需要可以迭代的内容,则可以在此处使用 iter() 而不是 list()。如果已传入列表,这将避免复制列表。
【解决方案2】:

我无法评论这是否出现在 PSW,但我通常更喜欢在这里使用三元而不是 try...catch 例如

def magnitude_of(v):
    return math.sqrt(sum([vi*vi for vi in (v if isinstance(v,list) else [v])]))

当然,正如其他人所提到的,如果函数只需要传递一个列表,那可能是最好的

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多