在函数内创建一个空列表,并将其传递给全局范围。 (在函数中初始化空列表)

时间:2019-02-15 16:08:34

标签: python python-3.x list function

我想创建一个函数,该函数接受一个列表,并在运行该列表时将一个项目添加到该列表中,因此基本上我将向该函数传递两个参数,第一个是我希望列表具有的名称,第二个是我要添加到列表中的项目。 我想以此作为学习练习,并且已经构建了一个功能,几乎可以完成我想要的功能。

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函数将无用(我必须添加另一个子句以检查列表是否已存在),但我的问题确实是关于在函数中初始化空白列表然后返回到全球范围。

3 个答案:

答案 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

  

注意:在您的函数中,print永远不会被调用,因为它位于return语句之后。

最后一路

最终,您还可以通过执行以下操作来缩短代码:

mylist = []
item = "test"
mylist.append(item.capitalize() if type(item) == str else item)

答案 2 :(得分:0)

首先,函数永远不要在调用范围内注入新名称。

  1. 如果函数使用全局变量,则需要对其进行记录,并且调用者必须在调用全局变量之前确保其存在。

  2. 如果函数带有参数,则有两个选项。一种,您可以对其进行突变并使函数返回None,也可以根据该参数创建一个 new 值并将其返回,而使参数保持不变。很少,如果有的话,您的函数应该修改参数 并返回值。

  3. 如果您的函数返回了一个新列表,则可以可选地获取一个列表进行修改,或者在函数内部创建一个全新的列表。

无关,但您不必在意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 = []

    # ...

但是,如果首先使用全局名称很糟糕,那么像这样自动实现它会变得更糟。尽可能避免这种编程方式。