关于Python列表元素和列表推导的一些问题
直接说重点。比如有一个列表 lst = [1, 1, 1, 0, 0, 0]
,现在我想把里面的1都改成0,变成 lst = [0, 0, 0, 0, 0, 0]
。
我最开始的解决方案是这样的:
for item in lst:
if item == 1:
item = 0
其实,结果列表还是 lst = [1, 1, 1, 0, 0, 0]
。
问题1: 除了用列表推导式,还有其他方法可以解决这个问题吗?
问题2: 当里面有很多 if else for
的时候,怎么写正确的列表推导式?我试过下面四种写法:
No.1 lst = [0 if item == 1 for item in lst] # Returns syntax error
No.2 lst = [0 for item in lst if item == 1] # Returns [0, 0, 0]
No.3 lst = [0 if item == 1 else item for item in lst] # Returns [0, 0, 0, 0, 0, 0]
No.4 lst = [0 for item in lst if item == 1 else item] # Returns syntax error
8 个回答
正如你所发现的,列表推导式的第三种写法是正确的。通常,使用一个辅助函数可以让这个过程更清晰:
def modify(value):
if value == 1:
return 0
else:
return value
lst = [modify(item) for item in lst]
如果你想用一个循环来实现同样的效果,可以使用 enumerate()
这个函数:
for index, item in enumerate(lst):
if item == 1:
lst[index] = 0
你可以这样做:
for x, item in enumerate(lst):
if item == 1:
lst[x] = 0
这样做是有效的,因为 enumerate 会返回一个迭代器,它会生成一个包含 (索引, 项目) 的元组。
通过这种方式,你可以检查项目的值,同时也知道你当前处于哪个索引,这样你就可以编辑引用。
至于第三个问题,你需要:
>>> lst = [1, 1, 1, 0, 0, 0]
>>> [0 if x == 1 else x for x in lst]
[0, 0, 0, 0, 0, 0]
>>>
列表推导和 for item in iterable
这两种方式都不会改变原来的列表。在列表推导的情况下,这是设计上就不允许的,而在后者中,是因为 Python 只通过值传递。
你可以使用 for 循环来改变特定位置的值,但在遍历的时候不要删除或添加任何东西。enumerate
让你可以同时获取列表中的项目和它们的索引。
for i, item in enumerate(lst):
if item == 1:
list[i] = 0
一般来说,列表推导的格式是 [表达式 for 目标 in 表达式 if 条件]
。最后的过滤部分是可选的,它只能跳过某个项目(可以理解为 if not 条件: continue
),选择放入生成列表中的项目是在第一个 表达式
中进行的。几版之前,增加了条件表达式(表达式 if 条件 else 表达式
),所以你可以在这个表达式中做一些基本的选择。不过在一个表达式中做两次或更多次这样的操作会让事情变得复杂,所以对于更复杂的逻辑,建议不要这样做。