我想创建一个函数,该函数接受一个列表,并在运行该列表时将一个项目添加到该列表中,因此基本上我将向该函数传递两个参数,第一个是我希望列表具有的名称,第二个是我要添加到列表中的项目。 我想以此作为学习练习,并且已经构建了一个功能,几乎可以完成我想要的功能。
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函数将无用(我必须添加另一个子句以检查列表是否已存在),但我的问题确实是关于在函数中初始化空白列表然后返回到全球范围。
答案 0 :(得分:1)
搁置关于这是否是一种好习惯的讨论(如果您的主要目标是增进了解,这可能会有所作为),您只需使用global keyword即可你所描述的。说
<xsl:template match="language[@source]">
<xsl:variable name="src" select="@source" />
<xsl:copy>
<xsl:copy-of select="@* | ../language[@target=$src]/@*[not(local-name(.) ='target') and not(local-name(.) ='lang')]"/>
</xsl:copy>
</xsl:template>
然后
def f(el):
global l
l.append(el)
如上所述,>>> l = []
>>> f(2)
>>> l
[2]
>>> f(3)
>>> l
[2, 3]
必须在使用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
答案 1 :(得分:0)
编写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
但这可能很棘手,因为列表是mutable objects。
注意:在您的函数中,
return
语句之后。
最终,您还可以通过执行以下操作来缩短代码:
mylist = []
item = "test"
mylist.append(item.capitalize() if type(item) == str else item)
答案 2 :(得分:0)
首先,函数永远不要在调用范围内注入新名称。
如果函数使用全局变量,则需要对其进行记录,并且调用者必须在调用全局变量之前确保其存在。
如果函数带有参数,则有两个选项。一种,您可以对其进行突变并使函数返回None
,也可以根据该参数创建一个 new 值并将其返回,而使参数保持不变。很少,如果有的话,您的函数应该修改参数 并返回值。
如果您的函数返回了一个新列表,则可以可选地获取一个列表进行修改,或者在函数内部创建一个全新的列表。
无关,但您不必在意item
的类型,仅是它具有可以调用的capitalize
方法。去尝试一下;否则,它将引发一个AttributeError
您可以捕获的情况,在这种情况下,您可以直接使用item
。
综合考虑所有这些,我推荐第三种方法。 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
,但不能使用其他列表。
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 = []
# ...
但是,如果首先使用全局名称很糟糕,那么像这样自动实现它会变得更糟。尽可能避免这种编程方式。