【问题标题】:Passing List Comprehension to a function in Python将列表理解传递给 Python 中的函数
【发布时间】:2015-06-18 14:21:01
【问题描述】:

我有一个函数,我想将列表理解作为输入传递给它。我收到关于 my_list 未定义的错误。我知道我可以将my_list 放在函数之外,但实际上该列表是作为函数的一部分生成的。

实际定义比较复杂,这里是简化的例子:

def my_def(list_comp):
    global my_list
    my_list = [[1,2],[3,4]]
    list_comp_output = list_comp
    return list_comp_output

print my_def([x[1] for x in my_list])

【问题讨论】:

  • [x[1] for x in my_list] 是一个列表推导,它产生一个列表,这个列表而不是推导传递给函数。所以你的简化函数返回输入列表并修改my_list
  • 在调用my_def([x[1] for x in my_list])时,python会计算表达式[x[1] for x in my_list]并将结果传递给my_def ... my_list需要在调用函数时定义...也是结果是静态的,所以即使你改变my_list它也不会改变
  • 另外,如果您的最终目标是创建一个函数,将某种函数(如 lambda x: x[1])应用于列表的所有元素......它已经存在,它是调用映射 => 见 map 函数

标签: python python-2.7 list-comprehension


【解决方案1】:

实际上 我们在 Python 中所拥有的只是运行时;没有单独的编译时间这样的东西1。(在解释器的范围内)。并且函数也不例外。

所以你在这里所做的就是将my_list 定义为一个全局变量,并尝试在列表推导中使用它,而python 没有定义这样的东西。

您可以只运行您的函数 1 次,然后使用该列表理解:

def my_def(list_comp):
    global my_list
    my_list = [[1,2],[3,4]]
    list_comp_output = list_comp
    return list_comp_output


my_def([])
print my_def([x[1] for x in my_list])
[2,4]

此外,我在这里看不到任何合乎逻辑的东西 :) 如果您想使用全局变量,只需在模块范围内定义 if(在函数之外并将其传递给您的函数。)

def my_def(list_comp):
    # do stuff with list_comp
    return list_comp_output


my_list= # a costume list 
li=[x[1] for x in my_list]
print my_def(li)

或者更优雅地在你的函数中做列表理解:

def my_def(list_comp):
    return [x[1] for x in list_comp]

1. Mark Lutz 的《学习 Python》

【讨论】:

  • 这回答了这个问题,但我猜有更好的方法来做 OP 想做的事情(虽然我不清楚那是什么)
  • @JulienSpronck 是的,我确实在这样做;)。
  • @Kasra 这确实完成了我的需要。我不想在函数中使用列表组合,因为我多次调用该函数并且每次都想使用不同的列表组合。
  • @user2242044 好的,但是为什么要在函数中定义my_list
  • @kasra 我认为我的示例只是过于简化了。该函数用于访问 API 并返回一些结果。 My_List 是 API 查询的结果。我多次调用该函数以从 API 获取各种数据。
【解决方案2】:

那是因为 my_list 没有定义;)

首先你必须意识到函数定义中的主体(但是如果有默认参数,这些将立即被评估)直到函数被实际调用才被执行,但它的参数在函数之前被评估函数被调用。

其中的前两个语句首先表示符号my_list 是该函数中全局范围的符号。第二个表示为该符号(在全局范围内)分配值[[1,2],[3,4]]。但这确实在调用函数之前不会发生(所以在函数定义之后它仍然没有定义)。

这样做的结果是您尝试在定义或分配给(在函数体中)之前评估 my_list(在调用函数时)。

您可以尝试通过首先调用my_def([]) 来实现它,这将定义my_list,但正确的方法可能是将my_list 的定义放在函数定义之外:

my_list = [[1,2],[3,4]]

def my_def(list_comp):
   list_comp_output = list_comp
   return list_comp_output

print my_def([x[1] for x in my_list])

这给出了答案:

[2, 4]

【讨论】:

  • my_def 在这里只是一个过于冗长的标识函数。你向它传递一个列表,它返回相同的列表。
  • “函数定义中的代码在函数被实际调用之前不会执行” - 但更重要的是函数的参数会被计算在调用函数之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2013-07-04
  • 1970-01-01
  • 2013-05-13
相关资源
最近更新 更多