【问题标题】:Inline for loop内联 for 循环
【发布时间】:2014-12-10 21:58:44
【问题描述】:

我正在尝试学习简洁的 Pythonic 做事方式,并且想知道为什么我的 for 循环不能以这种方式重构:

q  = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5]
vm = [-1, -1, -1, -1]

for v in vm:
    if v in q:
        p.append(q.index(v))
    else:
        p.append(99999)

vm[p.index(max(p))] = i

我尝试将 for 循环替换为:

[p.append(q.index(v)) if v in q else p.append(99999) for v in vm]

但它不起作用。 for v in vm: 循环根据 q 中的下一个数字从 vm 驱逐数字。

【问题讨论】:

  • 您可能希望使用 -1 而不是 99999 来标记不存在的值(因此它甚至适用于包含 99999+ 个元素的列表)
  • you list comprehsnsion 会起作用,但它也会返回 None 列表
  • 我使用了 99999 而不是 -1,因为后来我运行了一个 max(p) 并且需要选择不存在的值。

标签: python syntax list-comprehension


【解决方案1】:

您使用的在 Python 中称为 list comprehension,而不是内联 for 循环(尽管它与循环类似)。您可以将循环编写为列表理解,如下所示:

p = [q.index(v) if v in q else 99999 for v in vm]

使用列表推导式时,不要调用list.append,因为列表是由推导式本身构建的。列表中的每一项都将是 for 关键字左侧的表达式返回的内容,在本例中为 q.index(v) if v in q else 99999。顺便说一句,如果您确实在推导式中使用了list.append,那么您将获得None 值的列表,因为这是append 方法总是返回的。

【讨论】:

  • 谢谢老兄,太棒了! +互联网在一分钟内回答。
【解决方案2】:

您的列表 Comphresnion 将起作用,但将返回 None 列表,因为 append 返回 None:

演示:

>>> a=[]
>>> [ a.append(x) for x in range(10) ]
[None, None, None, None, None, None, None, None, None, None]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

像这样使用它的更好方法:

>>> a= [ x for x in range(10) ]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

【讨论】:

    【解决方案3】:

    您可以使用 enumerate 将元素的 ind/index 保留在 vm 中,如果您将 vm 设为 set 您还将有 0(1) 查找:

    vm = {-1, -1, -1, -1}
    
    print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ])
    

    【讨论】:

    • 酷炫的语法,感谢分享这看起来很有用!
    【解决方案4】:
    q  = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5]
    vm = [-1, -1, -1, -1,1,2,3,1]
    
    p = []
    for v in vm:
        if v in q:
            p.append(q.index(v))
        else:
            p.append(99999)
    
    print p
    p = [q.index(v) if v in q else 99999 for v in vm]
    print p
    

    输出:

    [99999, 99999, 99999, 99999, 0, 1, 2, 0]
    [99999, 99999, 99999, 99999, 0, 1, 2, 0]
    

    除了在列表推导中使用 append() 之外,您还可以将 p 引用为直接输出,并在 LC 中使用 q.index(v) 和 99999。

    不确定这是否是故意的,但请注意q.index(v) 只会找到v 的第一次出现,即使您在q 中有几个。如果要获取q 中所有v 的索引,请考虑使用enumerator 和已访问过的indexes 列表

    那些行中的东西(伪代码):

    visited = []
    for i, v in enumerator(vm):
       if i not in visited:
           p.append(q.index(v))
       else:
           p.append(q.index(v,max(visited))) # this line should only check for v in q after the index of max(visited)
       visited.append(i)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-07
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 2015-03-21
      • 2019-11-10
      • 2015-11-12
      相关资源
      最近更新 更多