-1

我对这里的代码有几个问题。我要做的是编写一个函数,该函数接受 2 个输入、一个列表和一个选项,选项为 0 或 1,并返回列表中的数字列表。如果选项为 0,它将返回大于 5 或​​小于 -5 的数字。如果选项为 1,它将返回第一个列表中所有奇数的列表。这就是我现在的代码:

def splitList(myList, option):
    nList = []
    for element in range(0,len(myList)):
        if option == 0:
            if myList[element] > 5:
                nList.append(element)
    return nList

现在我让它返回一个元素是否大于 5 的列表,但它返回它们在列表中的位置,而不是实际值。说我运行了程序

splitList([-6,4,7,8,3], 0)

它会返回 [2, 3]

我也希望它返回 7 和 8 以及 -6 的值,但我知道到目前为止我没有正确的代码来返回 -6。有人可以指导我正确的方向。另外,我想在这里使用 for 循环。如果选项为 1,我也不知道如何返回奇数。

这是我的有效代码:

def splitList(myList, option):
    nList = []
    for element in myList:
        if option == 0:
            if abs(element) > 5:
                nList.append(element)
        elif option == 1:
            if element % 2:
                nList.append(element)
    return nList

我怎么能把它切换到一个while循环?我尝试了以下代码,但似乎不起作用:

def splitList2(myList, option):
    nList = []
    element = 0 
    while element < len(myList):
        if option == 0:
            if abs(element) > 5:
                nList.append(element)
        elif option == 1:
            if element % 2:
                nList.append(element)
        element = element + 1
    return nList
4

4 回答 4

3

尽管命名了您的变量element,但它实际上是索引,而不是该索引处的元素。

你可以说出来,因为你必须用myList[element]它来比较它。

因此,要修复它,请再次执行相同的操作:

nList.append(myList[element])

但是,有一种更简单的方法可以做到这一点:直接循环遍历元素。

nList = []
for element in nList:
    if option == 0:
        if element > 5:
            nList.append(element)
return nList

你几乎不想循环range(len(spam))。通常,您只需要元素,因此只需循环spam自身。有时你需要索引元素,所以循环enumerate(spam). 如果你真的只需要索引......退后一步并确保你真的这样做(通常人们认为他们想要这个只是因为他们不知道zip,或者因为他们试图就地进行更改而不是复制,但是做它以一种行不通的方式)。

或者,更简单地说:

if option != 0:
    return []
return [element for element in nList if element > 5]

同时:

我也希望它返回 7 和 8 以及 -6 的值,但我知道到目前为止我没有正确的代码来返回 -6。

您可以将您的英语直接翻译成 Python:

它将返回大于 5 或​​小于 -5 的数字

… 是:

… element > 5 or element < -5 …

但是,如果您理解的话,有一种更简单的方法来编写它:

… abs(element) > 5 …

因此,这使选项 0 起作用。选项1呢?

判断一个数是否为奇数的一种简单方法是是否number % 2非零。

所以,让我们把它们放在一起:

if option == 0:
    return [element for element in nList if abs(element) > 5]
elif option == 1:
    return [element for element in nList if element % 2]
else:
    raise ValueError("I don't know option {}".format(option))

来自评论:

我如何将其更改为 while 循环?

要将for循环变为while循环,您必须将其分为三个部分:初始化循环变量,编写while测试和更新主体内部的循环变量。一般翻译是这样的:

for element in iterable:
    spam(element)

it = iterator(iterable)
while True:
    try:
        element = next(it)
    except StopIteration:
        break
    else:
        spam(element)

丑陋,不是吗?但通常,您可以针对您的情况提出一些更简单的方法。例如,如果 iterable 是一个序列,列出 a list,你可以这样做:

index, size = 0, len(sequence)
while index < size:
    spam(sequence[index])
    index += 1

仍然没有for循环那么好,但也没有泛型那么难看while


最后,只是为了好玩。每个人都知道函数映射比elif链更 Pythonic,对吧?为了证明像这样教条地遵循规则的价值,让我们在这里做:

preds = {0: lambda x: abs(x) > 5,
         1: lambda x: x % 2}
def splitList(myList, option):
    return filter(preds[option], myList)
于 2013-10-08T21:56:57.673 回答
1

似乎您应该只编写两个单独的函数,因为您尝试添加选项的函数会做不同的事情。

Python 让您可以轻松地迭代列表和其他数据结构:

for element in myList:
    if option == 0:
        if element > 5:
            nList.append(element)
    ....
于 2013-10-08T21:57:47.647 回答
0

问题的其他方面已经得到了很好的回答,但是在你的论点使用中有一个相当不合情理的结构。更好的是:

def extract_elements(my_list, odd_only):
    """Return select elements from my_list.

    If odd_only is True return the odd elements. 
    If odd_only is False return elements between -5 and 5 inclusive.
    """
    …

这里展示了四个重要的点:

  1. 名称非常重要,odd_only比 更具描述性,并且在不拆分任何内容时option调用方法会令人困惑。splitList
  2. 当语言具有内在布尔值时,不要使用任意整数来表示布尔选项。
  3. 该方法没有任何名称可以让读者理解其高度特殊的功能(并且extract_odd_or_magnitude_of_five难以键入并且仍然不是描述性的)。这就是为什么有docstrings,它们将方法的描述与方法定义非常紧密地绑定在一起。
  4. 公约事项。Python 风格指南可帮助其他人阅读您的代码。
于 2013-10-09T01:18:28.723 回答
0

因为单线很有趣:

def splitlist(li, flag):
    return [x for x in li if x%2==1] if flag else [x for x in li if abs(x)>5]

如果这是家庭作业,您可能不想上交这个答案,但它应该提供一些想法。

于 2013-10-08T22:02:55.867 回答