关于python list元素和列表推导的一些问题

时间:2011-03-29 15:56:25

标签: 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]。

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

8 个答案:

答案 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)就可以了。