在构建新列表时,应该如何一次循环遍历 Python 列表的两个元素?

How should one loop over two elements of a Python list at a time while building a new list?

假设我有一个数字列表,我想 "extend" 该列表中的元素超出一定数量。我应该如何通过添加分别是前后元素的平均值的元素来扩展列表?

numbers = [1, 2, 3, 4, 5]
minimumNumberOfElementsRequired = 15

# do magic here
# first iteration: [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]
# second iteration: [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]
# have sufficient number of elements => return list

print(numbers_extended)
# output: [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]

我的尝试开头如下:

list1 = [1, 2, 3, 4, 5]
list2 = [1, 2, 3, 4, 5]
index = -1
iterator = iter(list1)
for x, y in zip(iterator, iterator):
    index += 1
    list2.insert(index, (x + y) / float(2))

我想你可以这样做:

while len(numbers) < minimumNumberOfElementsRequired:
    index = 1
    while index < len(numbers):
        numbers.insert(index, (numbers[index-1] + numbers[index]) / 2.0)
        index += 2

这看起来有点尴尬,但这是解决插入引起的移动索引的最简单方法。

这不是最优雅的解决方案,但它确实有效。

numbers = [1,2,3,4,5]
while len(numbers) < 15:
    new_numbers = []
    for i, value in enumerate(numbers[:-1]):
        mean = (value + numbers[i+1])/2.0
        new_numbers.extend([value, mean])
    numbers = new_numbers + numbers[-1:]

您可以使用索引遍历数字,计算后续元素的平均值,并将其插入列表的正确位置。同时,需要注意的是index实际上是i*2,因为元素是在迭代时添加到列表中的。

while len(numbers) < minimum_length:
    for i in range(len(numbers) - 1):
        j = i*2
        a, b = numbers[j], numbers[j + 1]
        mean = (a + b)/2
        numbers.insert(j + 1, mean)

使用 reduce(根据 Yaroslav 管理员的建议)。

addnew 函数接受一个列表和一个要追加的新项目。

from functools import reduce    # if python3

numbers = [1, 2, 3, 4, 5]
minlen = 15

def addnew(lst, x):
    if lst:
        lst.append((lst[-1] + x)/2)
    lst.append(x)

    return lst

while len(numbers) <= minlen:
    numbers = reduce(addnew, numbers, [])

print(list(numbers))

这是一种迭代方法:

try:
    from itertools import izip
except ImportError:  # Python 3
    izip = zip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = iter(iterable), iter(iterable)
    next(b, None)
    return izip(a, b)

def add_means(num_list):
    r = [num_list[0]]
    for pair in pairwise(num_list):
        r.extend([sum(pair)/2.0, pair[1]])
    return r

def extend_list(numbers, min_elements):
    while len(numbers) < min_elements:
        numbers = add_means(numbers)

    return numbers

numbers = [1, 2, 3, 4, 5]
minimumNumberOfElementsRequired = 15

print(extend_list(numbers, minimumNumberOfElementsRequired))

输出:

[1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]