如何更简便地为嵌套列表的每个子列表首元素赋值?
解决嵌套列表批量修改子列表首元素的问题
嘿,这个坑我之前踩过!先给你掰扯清楚为啥T[:][0] = 10没效果,再给你几个简便的解决办法~
为啥T[:][0] = 10不生效?
你以为T[:]是取所有子列表,然后[0]是每个子列表的第一个元素?其实不是的:
T[:]会创建原外层列表的浅拷贝,相当于把[[0,0,0,0], [0,0,0,0], ...]复制了一份新的外层列表;- 然后
T[:][0]取的是这个拷贝里的第一个子列表,所以你执行T[:][0] = 10,只是把原列表的第一个子列表替换成了整数10,根本没碰其他子列表的元素。
简便的解决方法
方法1:列表推导式(生成新列表)
这是最简洁易读的方式之一,直接生成符合要求的新列表:
T = [[10] + row[1:] for row in T]
它会遍历原列表的每个子列表row,把10放在开头,后面拼接原row从第二个元素开始的部分,最终得到每个子列表首元素都是10的新嵌套列表。
方法2:原地修改的紧凑循环
如果不想生成新列表,想直接修改原列表,这个写法非常简洁,完全不啰嗦:
for row in T: row[0] = 10
虽然是循环,但一行核心逻辑就搞定,可读性拉满,而且是原地修改,内存效率也高。
方法3:用map函数(小众但可行)
如果你偏爱函数式写法,可以用map配合lambda实现,不过可读性稍弱一点:
list(map(lambda row: row.__setitem__(0, 10) or row, T))
这里row.__setitem__(0, 10)会原地修改子列表的首元素,它返回None,所以用or row返回修改后的子列表,map遍历所有子列表完成修改,最后转成列表(其实不转也能完成修改,转列表只是为了触发map的执行)。
总结
最推荐的是方法1(生成新列表)和方法2(原地修改),两者都简洁易读,完全满足你的“简便”需求~
内容的提问来源于stack exchange,提问作者Ashok
相关产品推荐
相关产品推荐

