【问题标题】:How to write a function that takes a positive integer N and returns a list of the first N natural numbers如何编写一个接受正整数 N 并返回前 N 个自然数列表的函数
【发布时间】:2013-09-16 03:01:20
【问题描述】:

I'm taking this online Python course 并尝试解决以下称为编码练习的问题:这是自然的:

编写一个函数 naturalNumbers,它接受一个正整数 n 作为输入,并返回一个由前 n 个自然数组成的列表 [1, 2, ...]。

我什至需要一个 for 循环来创建一个列表吗?这是我的代码(显然不起作用)。请记住,他们没有教过列表理解。我在 stackoverflow 上发现了这个概念。

def naturalNumbers(n):
   list = [n+1 for i in n]
   return list

我是否应该采取另一种方法,创建多个 1,2,3...n 列表并将它们连接在一起,如 [1] + [2] + [3]....

【问题讨论】:

  • 你的在线 Python 课程很奇怪。基本上要求你重新发明轮子(range 函数)
  • 事实上,你很难用一个列表来做到这一点。您的示例将给出一个错误,因为在 n 中没有任何内容可以循环,因为 n“不可迭代”
  • S Gupta - 这正是我的想法。
  • 尝试弄清楚如何实现内置函数有时很有用,这样您就可以了解它们在做什么,并看到使用它们的好处(for 循环 @987654327 @ 比带有显式计数器的 while 循环好得多),等等。出于类似的原因,我写了自己的itertools.groupby。但是,一旦你理解了事情,只需在你的真实代码和所有未来的学习中使用标准电池,当然。

标签: python list for-loop


【解决方案1】:

您的尝试有两个问题。

首先,您使用了n+1 而不是i+1,因此您将返回类似[5, 5, 5, 5] 而不是[1, 2, 3, 4]

其次,你不能for-循环像n这样的数字,你需要循环某种序列,比如range(n)

所以:

def naturalNumbers(n):
    return [i+1 for i in range(n)]

但是如果你已经有了range 函数,你根本就不需要这个;你可以return range(1, n+1),就像 arshaji 展示的那样。

那么,您将如何自己构建它?您没有要循环的序列,因此您必须使用 while 自己构建它,而不是 for

def naturalNumbers(n):
    results = []
    i = 1
    while i <= n:
        results.append(i)
        i += 1
    return results

当然,在实际代码中,您应该始终使用forrange,而不是手动执行操作。事实上,即使对于这个练习,最好先编写自己的range 函数,然后将其用于naturalNumbers。 (已经很接近了。)


如果你想变得聪明,还有一个选择。

如果你有一个列表,你可以对它进行切片。例如,my_list 的前 5 个元素是 my_list[:5]。因此,如果您有一个以1 开头的无限长列表,那将很容易。不幸的是,你不能有一个无限长的列表……但是你可以有一个很容易模拟的迭代器,或者通过使用count 或者通过编写你自己的 2 行等价物。而且,虽然您不能对迭代器进行切片,但您可以使用 islice 进行等效操作。所以:

from itertools import count, islice
def naturalNumbers(n):
    return list(islice(count(1), n))

【讨论】:

  • 所以,讲师只是回复了一条评论,说范围不是预期的解决方案。相反,我应该连接。关于如何做到这一点的任何想法?这似乎是“重新发明轮子”并且效率低下!
  • @StacyM:这肯定是编写实际代码的一种低效方式。但出于学习目的,它可能是一种有效的学习方式。例如,他可能试图向您展示冗长且容易出错的while 版本是什么样的,所以明天他可以向您展示更好的for 版本,您就会理解它。 (而且,将来,如果您发现自己编写了一个检查和递增 iwhile 循环,您会立即知道有更好的方法。)
  • @StacyM:无论如何,我认为他想要的是我丑陋的while 循环版本。我不知道他为什么说“连接”,因为通常这意味着extend+ 而不是append,我怀疑他是否真的希望你写results.extend([i]) 而不是results.append(i);可能他只是说错了。
  • @StacyM:如果你想变得聪明/烦人,你可能想先上交itertools 版本。他会告诉你这也不是他想要的答案,但值得看看他是否没有得到答案(在这种情况下你找错了教练)或者他是否只是不想要你超越自己……
【解决方案2】:

我什至需要 for 循环来创建列表吗?

不,您可以(并且在一般情况下应该)使用内置函数range()

>>> range(1,5)
[1, 2, 3, 4]

def naturalNumbers(n):
    return range(1, n + 1)

Python 3's range() 略有不同,它返回一个range 对象而不是一个列表,所以如果你使用 3.x 将它全部包装在list()list(range(1, n + 1))

【讨论】:

  • 类编译器出错并说它需要列表类型而不是范围。不过我明白你的意思。范围会容易得多。
  • @StacyM 参考答案最后一句。
  • @StacyM 他们在您链接到的页面上的示例中使用range
  • 3.x range 不返回生成器,它返回一个 range 对象,这是非常不同的。它不保留任何内部状态,您可以对其进行索引(例如,range(5)[3])等。事实上,它更像一个列表而不是一个生成器。但不会浪费列表的内存。
  • @arshajii:不。如果你想从技术角度而不是松散地谈论,那就更不正确了。它甚至不是一个迭代器。它不是一个列表,它具有常量而不是线性存储,但它是一个序列(实际上是一个collections.abc.Sequence),并且可以在您使用列表的大多数地方使用。
【解决方案3】:

这里有几种方法可以创建一个包含 N 个从 1 开始的连续自然数的列表。

1 个范围:

def numbers(n): 
    return range(1, n+1);

2 列表理解:

def numbers(n):
    return [i for i in range(1, n+1)]

您可能想研究 xrange 方法和生成器的概念,这些在 python 中很有趣。祝您学习顺利!

【讨论】:

  • 列表推导在这里没有任何用处。 [i for i in foo] 总是和list(foo) 一样,只是更慢、可读性更低、更冗长。如果您使用的是 Python 2.x(可能是,因为您提到了xrange),您已经拥有一个列表,所以[i for i in foo]list(foo) 都是 没必要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 2010-10-20
  • 2020-05-31
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多