对使用Python中的两个函数修改列表感到困惑

时间:2016-09-11 22:25:44

标签: python

我目前正在阅读Eric Matthes撰写的 Python Crash Course ,我很难理解第8章的全部功能。我坚持练习8-10,要求我使用新功能来更改上一练习中使用的列表。

以下是练习:

8-9. Magicians: Make a list of magician's names. Pass the list to a function called show_magicians(), which prints the name of each magician in the list.

8-10. Great Magicians: Start with a copy of your program from exercise 8-9. Write a function make_great() that modifies the list of magicians by adding the phrase the great to each magician's name. Call show_magicians() to see that the list has actually been modified.

以下是我的8-9代码:

def show_magicians(names):
    """Print each magician name"""
    for name in names:
        msg = name.title()
        print(msg)

magician_names = ['sonic', 'tails', 'knuckles']
show_magicians(magician_names)

我在这个网站上看到了一个非常相似的主题,所以我尝试使用本页第一个答案中的代码来帮助我:Python crash course 8-10

但是,我的代码似乎仍然不正确,因为编译器会在每个名称之后打印“好”3次。

以下是我用于8-10

的当前代码
def show_magicians(names):
    """Print each magician name"""
    for name in names:
        msg = name.title()
        print(msg)

magician_names = ['sonic', 'tails', 'knuckles']
show_magicians(magician_names)

def make_great(list_magicians):
    """Add 'Great' to each name."""
    for magician_name in magician_names:
        for i in range(len(list_magicians)):
            list_magicians[i] += " the great!"

make_great(magician_names)
show_magicians(magician_names)

我不知道为什么,但似乎我一直在努力完成整个功能章节。有没有人有任何推荐的教程来看看,以帮助我更好地理解功能?谢谢你的时间。

4 个答案:

答案 0 :(得分:2)

好的,所以你在外面有一个额外的循环,删除它。最终代码:

def show_magicians(names):
    """Print each magician name"""
    for name in names:
        msg = name.title()
        print(msg)

magician_names = ['sonic', 'tails', 'knuckles']
show_magicians(magician_names)

def make_great(list_magicians):
    """Add 'Great' to each name."""
    for index, item in enumerate(list_magicians):
        list_magicians[index] += " the great!"

make_great(magician_names)
show_magicians(magician_names)

你正在for-infor-in range一起做。这使得代码重复了字符串的追加。让我解释一下你以前的程序做了什么:

<强>说明: 在每次迭代中,您使用for-in进行循环,使其循环内循环3次。因此,在外部循环的每次迭代中,它将重复内部循环3次,使其为每个名称附加the great 3次。

此外,作为关联问题的回答者,我宁愿您使用enumerate而不是range(len(list_magicians))

答案 1 :(得分:1)

将第二种方法更改为:

def make_great(list_magicians):
    """Add 'Great' to each name."""
    i = 0
    for magician_name in magician_names:
        list_magicians[i] += " the great!"
        i += 1

目前,您使用两个for loops循环两次,导致它被添加3次!

答案 2 :(得分:1)

让我们看一下你的make_great函数:

def make_great(list_magicians):
    """Add 'Great' to each name."""
    for magician_name in magician_names:
        for i in range(len(list_magicians)):
            list_magicians[i] += " the great!"

这是做什么的?

for magician_name in magician_names:循环magician_names

for i in range(len(list_magicians)):按索引循环list_magicians

list_magicians[i] += " the great!"the great!添加到i的{​​{1}}元素

什么行代码不是必需的?

list_magicians通过此循环不起作用。由于它的长度为3,这就是为什么你会为每个元素添加3 for magician_name in magician_names:的原因。删除该行代码,该函数应该正常工作。

答案 3 :(得分:1)

正如另一个回答者所说,你的嵌套循环基本上做同样的事情,但每次外循环运行时,内循环运行。两个循环都试图遍历魔术师列表,一个使用列表在函数外部的名称(magician_names),另一个使用列表在函数内部的名称(list_magicians)。无论哪种方式都可行,但两者都太多了。从这个角度来看,你的误解不是功能,而是循环。

但是你在函数中提到magician_names的事实表明存在误解。它会起作用,但形式不好。通常,函数的代码应该专门引用通过参数传递给函数的名称。因此,在这种情况下,您应该放弃magician_names上的循环并将循环保持在list_magician之上。规则有例外,但在打破它之前你应该有一个明确的理由。该规则的理由是封装:您可以通过读取其参数列表及其代码来完全理解该函数,而无需询问函数之外的任何角色。

如果您接受这样的想法,即函数应仅对其参数进行操作,那么您必须问,那么函数如何影响外部世界?一个答案是函数return是一个东西,而外界自愿对返回的东西做了些什么。另一个答案是函数的参数碰巧指向外部世界中的对象,因此更改函数内部的对象会自动将其更改为函数外部。我更喜欢第一种方式,但在你的情况下使用第二种方式可能更容易。因此,当您将magician_names传递给函数时,Python会将其重命名为list_magicians;你在函数内部运行list_magicians,因此magician_names也会在函数外部发生变化;从函数返回,名称 list_magicians消失,但更改magician_names存活。

这是最后一点建议,它将您的知识扩展到列表推理,&#34;你可能还没有学到的主题(但它们对于这个应用程序非常完美):我建议编写一个函数来操作单个数据,然后重复调用该函数,而不是尝试做同一功能中的重复和单项数据修改。像这样:

def append_great(magician):
    return magician + " the Great"

有了这个功能,列表理解看起来很不错。它根据您的指示逐个元素地处理列表元素。像这样:

>>> magicians = [ "Houdini", "Fubini" ]
>>> [ append_great(m) for m in magicians ]
['Houdini the Great', 'Fubini the Great']

请注意,列表推导返回了一个新列表; magicians保持不变,除非您自己更改。事情应该是怎样的。功能不应该伸出并触及外面的世界(除非这是一个非常好的理由);相反,外界应该向函数提供一些数据,接收结果,并在外界知道最佳时使用结果。这是我对影响外部世界的回归价值方式的倡导,但正如我所说,在这种情况下,使用传递参考方式更容易。