直言不讳。例如一个列表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]。
Q1 :除了使用列表理解之外,还有其他解决办法吗?
Q2 :当更多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
答案 0 :(得分:3)
你可以这样做:
for x, item in enumerate(lst):
if item == 1:
lst[x] = 0
这是有效的,因为enumerate返回一个产生(index,item)元组的迭代器
通过这种方式,您可以检查项目的值,还可以了解当前所使用的索引,以便编辑参考。
要回答3号,你想要:
>>> lst = [1, 1, 1, 0, 0, 0]
>>> [0 if x == 1 else x for x in lst]
[0, 0, 0, 0, 0, 0]
>>>
答案 1 :(得分:3)
列表理解和for item in iterable
都不会改变列表。在前一种情况下,(实际上)设计是不可能的,在后一种情况下,因为Python只是通过值传递。
您可以使用for循环并更改特定索引处的值。只是在迭代时不要删除或添加任何内容。 enumerate
允许你吃蛋糕(项目)并吃掉它(必须索引)。
for i, item in enumerate(lst):
if item == 1:
list[i] = 0
列表理解一般为[expression for target in expression if condition]
形式。最后的可选过滤部分只能跳过一个项目(将其视为if not condition: continue
),选择要放入列表中的项目将在第一个expression
中生成 - 几个版本之前,有条件的添加了表达式(expression if condition else expression
),因此您可以在该表达式中进行一些基本选择。在一个表达式中执行两次或更多操作确实会推动它,所以不要使用它来处理更复杂的逻辑。
答案 2 :(得分:1)
Q1。 for循环中对iteratee的赋值不会反映回列表。您需要使用正常的a[b]=c
语法来回发更改
for i, item in enumerate(lst):
if item == 1:
lst[i] = 0
Q2。第3名。
x if y else z
是Python中的一个特殊表达式。这与C语言中的y ? x : z
相对应。您不能忽略else
部分,因此数字1是语法错误。
数字2表示只会发出满足item == 1
的项目。一个更好的说明示例:
>>> [i for i in range(10) if i % 4 == 0]
[0, 4, 8]
答案 3 :(得分:1)
正如你所知,列表理解没有。 3是正确的语法。通常,辅助函数可以使其更清晰:
def modify(value):
if value == 1:
return 0
else:
return value
lst = [modify(item) for item in lst]
要使用for循环实现相同的效果,您可以使用enumerate()
:
for index, item in enumerate(lst):
if item == 1:
lst[index] = 0
答案 4 :(得分:0)
lst = [0 for item in lst]
可能是最简单的。也许不是最快的(特别是有数百万和数十亿元素)。
您也可以尝试lst = [ 0 if item==1 else 0 for item in lst]
答案 5 :(得分:0)
在for
循环中,您正在使用列表元素的副本,而不是实际列表。在任何情况下迭代序列时修改序列是不安全的。
你可以这样做:
while 1 in lst:
lst[lst.index(1)] = 0
在没有列表理解的情况下实现您想要的目标。
答案 6 :(得分:0)
for
循环无效的原因是更改item
的值只会更改item
的值。 item
最初指向列表中的相同元素,但重新分配它只会更改它指向的内容;它不会修改列表元素。
要实际修改列表,您需要知道您正在查看的列表中的哪个项目。您可以使用enumerate()
来执行此操作,这样您就可以访问循环体内的项目值及其索引(列表中的位置)。
for index, item in enumerate(lst):
if item == 1:
lst[index] = 0
这样做(而不是像其他人所建议的那样使用列表理解)确实具有不制作列表的另一个副本的优点,这在列表很大时可能很有用。
答案 7 :(得分:0)
如果要就地更新列表(即不创建新列表),则以下代码将起作用:
for index, item in enumerate(lst):
if item == 1:
lst[i] = 0
在原始代码中,每次循环时,变量item
都会被分配列表中的下一个值,然后如果该值为1,则将0分配给item
,但这样做不更改列表 - 它只是更改变量item
。
要创建新列表,您的解决方案(3)就可以了。