如何改变列表中的每三个元素?

How do I mutate every third element in a list?

如何检查列表中的每三个元素?

即。鉴于下面的列表,我想改变每三个项目并保持列表的其余部分不变。

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

基本上,如果列表中的第三个元素(在本例中为 3,6,9)为奇数,则减一使其为偶数。如果是偶数,就让它保持不变。

我知道如果我这样做 L[2::3] 我会得到一个包含每三个元素的新列表,但我只是想遍历每三个元素并检查。

for 循环会是什么样子?我需要一些帮助。

感谢并感谢所有帮助!

定义要应用到元素的函数并使用列表理解进行迭代

def do(number):
    if number%2 == 1:
        return number -1
    else:
        return number

[do(y) if i%3 == 0 else y for i,y in enumerate(L)]

不明确使用 enumerate 的不同解决方案可能是:

for i in range(len(L)):
    if i%3 == 0:
        L[i] = do(L[i])

您可能还想检查 关于镶嵌操作

列表理解是最佳选择:

L = [1,2,3,4,5,6,7,8,9]
L[2::3] = [i-1 if (i%3==0 and i%2!= 0) else i for i in L[2::3]
print(L)

输出:

[1, 2, 2, 4, 5, 6, 7, 8, 8]

解释:

基本上你查看 L 中的每个 third 元素,看看它是否可以被 3 整除(余数为 0)并且不能被整除(mod2 不为 0),如果可以,则减去1 从它,否则保持原样。替换原始列表中的结果。

您可以使用切片来根据条件修改所选值来进行列表推导:

L[2::3] = [x - 1 if x % 2 else x for x in L[2::3]]

示例

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

L[2::3] = [x - 1 if x % 2 else x for x in L[2::3]]
# [1, 2, 2, 4, 5, 6, 7, 8, 8]

您可以分配给切片,在此示例中,然后使用列表推导来进行突变。

L = [1,2,3,4,5,6,7,8,9]
L[2::3] = [ x if x % 2 == 0 else x-1 for x in L[2::3] ]
print(L)

尽管句法优美,但简单的 for 循环更适合您未来的自己和同事 =D

不要想太多。在这种情况下,列表推导式、函数等都是多余的。您需要遍历列表并就地修改它,对吗?所以你没有修改你正在迭代的结构。迭代目标其实就是list的indices

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

print(xs)

for idx in range(2, len(xs), 3):
    if xs[idx] % 2 == 1:
        xs[idx] -= 1

print(xs)

这相当于许多低级语言中的 for(i = 2; i < len(xs); i++) 循环。


与另一个答案中提出的列表理解解决方案相比,for 循环稍微快一些:

from timeit import timeit


def in_place(xs):
    for idx in range(2, len(xs), 3):
        if xs[idx] % 2 == 1:
            xs[idx] -= 1
    return xs


def list_comp(xs):
    xs[2::3] = [i - 1 if (i % 3 == 0 and i % 2 != 0) else i for i in xs[2::3]]
    return xs


# This answer is an improvement, as it eliminates one modulus
def list_comp2(xs):
    xs[2::3] = [x - 1 if x % 2 else x for x in xs[2::3]]
    return xs


context = {"globals": globals(), "setup": "xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]"}
print(f"For loop: {timeit('in_place(xs)', **context)}")
print(f"List comprehension:  {timeit('list_comp(xs)', **context)}")
print(f"List comprehension 2:  {timeit('list_comp2(xs)', **context)}")

在我的机器上,这会产生:

For loop: 0.608657514
List comprehension:  0.7510721879999999
List comprehension 2:  0.641639047