将列表的每三个元素乘以2

时间:2019-05-29 23:10:25

标签: python list collections iteration list-comprehension

输入数据:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
输出数据:[1, 2, 6, 4, 5, 12, 7, 8, 18, 10]

我阅读了许多答案,建议在其中使用包含第一个元素的切片符号。但就我而言,我应该将列表的每个第3个元素都包含在内。

是否可以提高我的认识?

for index in range(len(data)):
    if (index + 1) % 3 == 0:
        data[index] = data[index] * 2

6 个答案:

答案 0 :(得分:9)

是的,您可以使用切片符号来实现:

data[2::3] = [x*2 for x in data[2::3]]

data[2::3]表示从元素索引2(即第三个元素)开始的每个第三个元素。您也可以重新分配给切片,以使用这种非常简洁的语法。

答案 1 :(得分:3)

range迭代器上有一个“ step”参数:

for index in range(2, len(data), 3):
    data[index] *= 2

那会吗?

答案 2 :(得分:3)

您的解决方案还不错。可以通过直接直接遍历所需索引而不是遍历所有索引并跳过不想要的索引来改进它:

for index in range(2, len(data), 3):
    data[index] *= 2

这将产生所需的结果:

[1, 2, 6, 4, 5, 12, 7, 8, 18, 10]

答案 3 :(得分:2)

您可以使用itertools和zip中的cycle将项目与其乘数配对:

data   = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

from itertools import cycle
result = [n*m for n,m in zip(data,cycle([1,1,2]))]

# [1, 2, 6, 4, 5, 12, 7, 8, 18, 10]

或者,您可以使用enumerate()

result = [ n*max(1,i%3) for i,n in enumerate(data) ]

答案 4 :(得分:1)

您可以通过将第三个参数传递给range()函数来对其进行组织,如下所示:

for index in range(2, len(data), 3): data[index] = data[index]*2

答案 5 :(得分:1)

...而获胜者是:

Calculation time in seconds and results validation test.
1.150 question_by_akrapovich
0.331 answer_by_Tom_Karzes_and_Prune
0.333 answer_2_by_Manuel_Montoya
0.373 answer_by_Blorgbeard
0.816 answer_1_by_Alain_T
2.850 answer_2_by_Alain_T

用于时间测试和结果验证的组合代码:

import time


def question_by_akrapovich(data):
    for index in range(len(data)):
        if (index + 1) % 3 == 0:
            data[index] = data[index] * 2
    return data


def answer_by_Tom_Karzes_and_Prune(data):
    for index in range(2, len(data), 3):
        data[index] *= 2
    return data


def answer_by_Blorgbeard(data):
    data[2::3] = [x*2 for x in data[2::3]]
    return data


def answer_1_by_Alain_T(data):
    from itertools import cycle
    return [n * m for n, m in zip(data, cycle([1, 1, 2]))]


def answer_2_by_Alain_T(data):
    return [ n*max(1,i%3) for i,n in enumerate(data) ]


def answer_2_by_Manuel_Montoya(data):
    for index in range(2, len(data), 3):
        data[index] = data[index]*2
    return  data

def test(f):
    n = 10_000_000
    data = [i + 1 for i in range(n)]
    start_time = time.perf_counter()
    data = f(data)
    run_time = time.perf_counter() - start_time
    if n != len(data):
        print('error in list length', n, len(data))
        exit(1)
    for i in range(n):
        j = i + 1
        m = j * 2 if j % 3 == 0 else j
        if data[i] != m:
            print('error in data', i, m, data[i])
            exit(1)
    print('%.3f %s' % (run_time, f.__name__))


print('Calculation time in seconds and results validation test.')
for f in [question_by_akrapovich, answer_by_Tom_Karzes_and_Prune,
          answer_2_by_Manuel_Montoya, answer_by_Blorgbeard,
          answer_1_by_Alain_T, answer_2_by_Alain_T]:
    test(f)