Python 如何对列表中的每三个元素进行变异?

Python 如何对列表中的每三个元素进行变异?,python,python-3.x,list,mutation,Python,Python 3.x,List,Mutation,如何检查列表中的每三个元素 例如,鉴于下面的列表,我想每三个项目进行一次变异,并保持列表的其余部分不变 L=[1,2,3,4,5,6,7,8,9] 基本上,如果列表中的第三个元素(在本例中为3,6,9)为奇数,则减去1使其为偶数。如果是偶数,就让它保持不变 我知道如果我做了L[2::3]我会得到每三个元素的新列表,但我只想循环检查每三个元素并进行检查 for循环是什么样子的?我需要一些帮助 感谢并感谢所有的帮助 定义要应用于元素的函数,并使用列表进行迭代 def do(number):

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

例如,鉴于下面的列表,我想每三个项目进行一次变异,并保持列表的其余部分不变

L=[1,2,3,4,5,6,7,8,9]
基本上,如果列表中的第三个元素(在本例中为
3,6,9
)为奇数,则减去1使其为偶数。如果是偶数,就让它保持不变

我知道如果我做了
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)]
不明确使用
枚举
的其他解决方案可能是:

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)
输出: 说明:
基本上你看L中的第三个元素,看看它是否可以被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如果x%2==0,则x-1表示L[2::3]]
印刷品(L)
尽管语法很漂亮,但简单的for循环更适合你未来的自我,同事们=D

不要想太多。在这种情况下,列表理解、函数等都是多余的。你需要迭代一个列表,并在适当的地方修改它,对吗?因此,您没有修改正在迭代的结构。迭代目标实际上是列表的索引

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)
这相当于许多低级语言中的(i=2;i循环


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

从timeit导入timeit
def就地(xs):
对于范围内的idx(2,len(xs),3):
如果xs[idx]%2==1:
xs[idx]-=1
返回xs
def列表组件(xs):
xs[2::3]=[i-1 if(i%3==0和i%2!=0)else i for i in xs[2::3]]
返回xs
#这个答案是一个改进,因为它消除了一个模数
def列表组件2(xs):
xs[2::3]=[x-1如果x%2,则为x,在xs[2::3]中为x]
返回xs
context={“globals”:globals(),“setup”:“xs=[1,2,3,4,5,6,7,8,9]”
打印(f“For循环:{timeit('in_place(xs),**context)}”)
打印(f“列表理解:{timeit('List_comp(xs),**context)}”)
打印(f“列表理解2:{timeit('List_comp2(xs),**context)}”)
在我的机器上,这会产生:

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

谢谢你知道有没有一种不使用枚举的循环方法吗?你需要迭代计数来跟踪增量。我明白了,非常感谢!因为我刚刚醒来:)。换了。谢谢但这是一个要求
基本上,如果列表中的第三个元素(在本例中为3,6,9)为奇数,则减去1使其为偶数。如果它是偶数,就让它保持不变。
您可能知道这一点,但为了安全起见:首先复制一份列表,并对其进行迭代,然后对另一个列表进行变异。正如雷蒙德·海廷格(Raymond Hettinger)曾经说过的,“如果你在迭代过程中对某个东西进行了变异,那么你就生活在一种罪恶的状态中,你应该得到发生在你身上的一切。”而且,这似乎使问题变得过于复杂,因此条件变得更加简单。请参阅我的答案以了解我的意思。@lbragile,请参阅我对您的答案的评论。只是想知道您为什么要专门分配回切片列表?这不能是任何变量吗?OP希望保留列表中的所有其他元素。我们获取切片,修改并将其放回切片,因此所有其他元素保持不变。您可以使用:
如果xs[idx]%2:
并且我不同意“……等等都是多余的”。尽管这个答案可能会产生正确的输出,但它将比具有列表理解能力的方法慢得多,甚至更不清晰。因此,我认为你应该考虑接受@奥斯丁或我的答案,因为它们基本上是一个内衬,整体速度要快得多。我的直觉是,在这种情况下,列表理解会慢一些,所以我写了一个基准。我已将其添加到帖子中。我还将坚持我的观点,即for循环是一种几乎通用的构造,与Python极不寻常的list-slice赋值相比,它更易于阅读,而在编写Python的多年中,我从未在实际代码中使用过它。打高尔夫球?对真代码?不。(从@Austin的答案中添加另一个列表理解;由于只使用了一个模运算符,它的性能更好。)
timeit是的一部分,它多次运行其片段。在这种情况下,100万(默认值)。无论如何,你是对的,差别并不是特别显著;可读性上的差异更为重要。一个小小的简化:
L[2::3]=[x-x%2代表L[2::3]]
For loop: 0.608657514
List comprehension:  0.7510721879999999
List comprehension 2:  0.641639047