Python 在函数中生成空列表并将其传递给全局范围。(初始化函数中的空列表)
我想创建一个函数,在我运行它的时候,生成一个列表并向该列表中添加一个项,所以基本上我会向这个函数传递两个参数,第一个是我希望列表具有的名称,第二个是我希望添加到列表中的项。 我想把它作为一个学习练习来做,我已经构建了一个函数,它几乎可以完成我想要它做的事情Python 在函数中生成空列表并将其传递给全局范围。(初始化函数中的空列表),python,python-3.x,list,function,Python,Python 3.x,List,Function,我想创建一个函数,在我运行它的时候,生成一个列表并向该列表中添加一个项,所以基本上我会向这个函数传递两个参数,第一个是我希望列表具有的名称,第二个是我希望添加到列表中的项。 我想把它作为一个学习练习来做,我已经构建了一个函数,它几乎可以完成我想要它做的事情 def addlst(l, item): """add an item to a list""" l = list()#this line essentially does nothing.
def addlst(l, item):
"""add an item to a list"""
l = list()#this line essentially does nothing.
if type(item) == str:
l.append(item.capitalize())
return l
print(l)
else:
l.append(item)
return l
print(l)
如果我通过这个,比如:
addlst(people, 'kev')
我得到一个错误:
NameError: name 'people' is not defined
但是很明显,如果我把人定义为一个空列表,它就可以正常工作
我现在所做的真的可能吗?我知道,因为这是底线
l = list()
只需先清空列表,因此append函数将是无用的(我必须添加另一个子句来检查列表是否已经存在),但我的问题实际上是在函数中初始化一个空白列表,然后将其返回到全局范围。搁置关于它是否是一个良好实践的讨论,(如果你的主要目标是提高你的理解力,那么这很有意义),你可以简单地使用
def f(el):
global l
l.append(el)
然后
如上所述,l
必须在使用f
之前声明
针对你的特点,你可以做的是:
def addlst(item):
"""add an item to a list"""
global l#
if isinstance(item, str): # type(item) == str is not recommanded
item = item.capitalize()
l.append(item)
但实际上,请注意,这样做将“绑定”您的函数,以便专门处理全局范围内名为l
的列表。看起来这不是您想要的,因为您似乎希望能够将多个列表对象传递给您的函数。最好的方法是
def addlst(list_, item):
"""add an item to a list"""
if isinstance(item, str):
item = item.capitalize()
list_.append(item)
return list_
当您编写
addlst(people,'kev')
时,您告诉您的代码您想要执行addlst
函数,其中变量命名为people
问题是:您从未设置此变量
有多种方法可以实现此目的;您可以在调用函数之前初始化空列表:
people = []
addlst(people, 'kev')
或者使用默认值将参数设置为可选:
def addlst(item, l = None):
"""add an item to a list"""
if l is None:
l = []
if type(item) == str:
l.append(item.capitalize())
return l
else:
l.append(item)
return l
但这可能会很棘手,因为列表很复杂
注意:在函数中,print
永远不会被调用,因为它位于return
语句之后
最后一条路
最终,您还可以通过这样做来缩短代码:
mylist = []
item = "test"
mylist.append(item.capitalize() if type(item) == str else item)
首先:函数不应该将新名称注入调用范围
None
,或者您可以基于参数创建一个新值并返回该值,保持参数不变。如果函数修改参数并返回值,则这种情况非常罕见项的类型,只需要它具有一个可以调用的大写
方法。试试看;如果没有,它将引发一个您可以捕获的AttributeError
,在这种情况下,您只需按原样使用项即可
综上所述,我推荐第三种方法。add_to_list
将一个项目作为第一个参数,一个可选的列表作为第二个参数。如果没有给出列表,函数将创建一个新列表。在任何一种情况下,您都会将适当修改的项目附加到列表中并返回它
def add_to_list(item, l=None):
# Note: this doesn't change the item you pass; it just rebinds
# the local name item to a *new* string if it succeeds.
try:
item = item.capitalize()
except AttributeError:
pass
if l is None:
l = []
return l + [item]
然后你可以用
people = add_to_list('kev') # people == ['Kev']
people = add_to_list('bob') # people == ['Bob'], Kev is gone!
people = add_to_list('kev', people) # people == ['Bob', 'Kev'], Kev is back.
第二种方法中提到的更有效的版本修改了l
;但是在这种情况下,您必须提供一个列表;您不能创建新的列表
def add_to_list(item, l):
try:
item = item.capitalize()
except AttributeError:
pass
l.append(item)
people = [] # Create the list in the *calling* scope, not in add_to_list
add_to_list('kev') # TypeError, missing an argument
add_to_list('kev', people) # people == ['Kev']
add_to_list('bob', people) # people == ['Kev', 'Bob']
第一种方法非常糟糕;它限制您的函数使用特定的列表,该列表的名称在函数中是硬编码的,但为了完整性,我在这里提到它。由于列表是硬编码的,我们将更改函数的名称以反映这一点
def add_to_people(item):
global people
try:
item = item.capitalize()
except AttributeError:
pass
people.append(item)
现在,add_to_list
可以处理全局列表人员
,但不能处理其他列表
people = []
add_to_people('kev')
add_to_people('bob')
最后,为了充分披露,是的,add_to_people
可以创建列表,如果它还没有:
def add_to_people(item):
global people
try:
people # Simply try to evaluate the name
except NameError:
people = []
# ...
但是,如果首先使用全局名称是不好的,那么像这样自动激活它就更糟糕了。尽可能避免这种编程方式。只需在函数定义中键入global l
,就可以全局使用l
。addList
本身无法(轻松地)并且不应在调用范围中创建新名称。第一个参数必须是现有列表。我通常同意@chepner,但觉得动态创建变量(无论其范围如何)是一种糟糕的编程实践。我确信这是一个糟糕的做法,我两周前开始编写代码,我是个白痴。我一直在练习制作列表,然后记录数据帧,然后玩dfs,我只是想要一个函数来制作列表并快速添加内容。正确的做法是返回列表,让调用方将返回值分配给他们想要的任何名称。第二个可选参数(如中所示)可以是一个要返回的现有列表(附加到该列表后),而不是创建一个新列表。虽然如此,我是否仍必须在函数外部初始化l?@kevomaley743是。如果您在没有先声明l=[]的情况下执行f(2)
,你会得到一个错误;非常感谢你花时间。@martineau实际上,我对没有被否决感到惊讶:)另外,如果我错了,请纠正我,但你甚至不需要使用global
语句将项目附加到列表中……你的f()
方法没有它应该可以工作。这不是一个好主意
def add_to_people(item):
global people
try:
people # Simply try to evaluate the name
except NameError:
people = []
# ...