如何创建一个列表,其中每个新元素作为最后一个元素加上一个常量?

时间:2017-06-06 15:14:22

标签: python python-2.7 list

鉴于这些变量:

a_4th =  6.08
delta_a = 0.052

我想创建一个包含以下内容的列表:

a = [a_4th, a_5th, a_6th, a_7th ... ]

其中:

a_5th = a_4th + delta_a
a_6th = a_5th + delta_a
a_7th = a_6th + delta_a

此代码:

a = []  # create the empty list
a.insert(0, a_4th) # initialize the 1st item of the list

for i in xrange (1,19):   # I would like the list to be 18 items long. 
                          # a[0] is defined in the previous line.
  a[i] = a[i-1] + delta_a 

发出此错误:

Traceback (most recent call last):
  File "so.py", line 8, in <module>
    a[i] = a[i-1] + delta_a 
IndexError: list assignment index out of range

4 个答案:

答案 0 :(得分:5)

这种理解怎么样?

a_4th =  6.08
delta_a = 0.052
a = [a_4th + i * delta_a for i in range(20)]

或您的代码,已修复

a_4th =  6.08
delta_a = 0.052
a = [a_4th]
for i in xrange (1,19):
  a.append(a[i-1] + delta_a)  # or the elegant a.append(a[-1] + delta_a) kudos @Prune

另请注意,从列表理解的速度优势来看,它也适用于Python 2.xPython 3.x发行版,因此更易于维护。

答案 1 :(得分:3)

让我们清理你的代码:

a = []  # create the empty list
a.insert(0, a_4th) # initialize the 1st item of the list

这在阅读和执行方面都会浪费精力。只需初始化列表:

a = [a_4th]

对于循环,您不能分配给不存在的列表元素。您可以使用appendinsert,连接或其他已定义的操作创建新的列表元素。

for i in xrange (1,19):   # I would like the list to be 18 items long. 
                          # a[0] is defined in the previous line.
  a.append( a[-1] + delta_a )

是的,我从i删除了i-1;这引入了另一种错误的可能性。只需使用列表的最后一个(索引减一)元素。

答案 2 :(得分:3)

如果我是你,我会使用Python生成器,因为它可以提供额外的表现力,能够表达&#34;无限的&#34;大序列。

def succession(initial, delta):
  while True:        
    yield initial
    # value, then, the next time you call 
    initial += delta

values_generator = succession(6.08, 0.052)

# later we decide how many values we want to consume from the generator
for i in range(20):
  print(next(values_generator))

更新

添加有关生成器的更多说明。生成器是Python提供的一种机制,允许构建高效的数据处理管道。

假设你有一个从0到100_000的数字列表,如果你使用常规的Python2 mapfilter,你想要对它进行一些转换,比如过滤,然后映射等等。您的解决方案不会很好地扩展,因为在每个步骤(过滤,映射等)中,将计算可能甚至不会在最终结果中使用的潜在许多元素的整个新的中间结果列表。构建这些功能管道的关键思想是我们希望它们是组合器,即我们可以组合起来创建新功能的小功能,以后可以组合使用,但我们不会想要付出代价。生成器基本上是用Python来解决这个问题的(在Clojure中你有传感器和Haskell懒惰评估)。使用生成器Python不会构建中间列表,而是在管道的一端推送一个值,对其进行转换,然后将其弹出另一端,这对于您希望转换的初始数据集中的每个元素都是如此。 / p>

生成器的一个简单示例是:

def trivial_generator():
  print "running until first yield..."
  yield 1
  print "running until second yield..."
  yield 2
  print "exiting..."


generator = trivial_generator()

result = generator.next()
print "got result ", result
result = generator.next()
print "got result ", result
generator.next()

如果你跑了,你会得到:

running until first yield...
got result  1
running until second yield...
got result  2
exiting...
Traceback (most recent call last):
  File "foo.py", line 14, in <module>
    generator.next()
StopIteration

说明了生成器的行为:

  1. 您可以通过调用包含yield
  2. 的函数来创建一个
  3. 每当您调用.next()方法或将其传递给next(generator)函数时,生成器的主体将被执行,直到找到yield
  4. 当找到yield时,将返回yield中指定的值,并且生成器将保持暂停,直到再次调用其.next()方法为止,此时它将从暂停的最后一点恢复(注意发电机的所有内部状态都保持在通话之间)
  5. 如果您在生成器上调用.next()而没有找到其他yield(这意味着它的结尾),则会引发StopIteration(这是非常方便的,因为它是例外期望for循环发生在迭代器的开头)
  6. 在我使用的示例解决方案中,我利用了生成器的暂停/恢复功能,将yield置于无限循环中,我得到了一个生成器,它将为我提供尽可能多的有效值。

答案 3 :(得分:1)

简单明了的解决方案:

a = []
a.append(a_4th)
for i in xrange(1, 19):
    a.append(a[i-1] + delta_a)

但是根据你的定义:

  

a_5th = a_4th + delta_a

     

a_6th = a_5th + delta_a

     

a_7th = a_6th + delta_a

我们可以更简单地将其视为:

  

a_5th = a_4th +(delta_a * 1)

     

a_6th = a_4th +(delta_a * 2)

     

a_7th = a_4th +(delta_a * 3)

并将其写为简单(且更快)的列表理解,参见Ev Kounis的答案。