【问题标题】:How to convert this for-loop with a comparison into a list comprehension?如何将此带有比较的for循环转换为列表理解?
【发布时间】:2021-05-27 04:10:22
【问题描述】:

我正在尝试更好地使用列表推导,并且此代码适用于我使用它的目的(代码挑战),但我想使用列表推导并了解它的工作原理。

j = 0
for i in range(len(a)):
    if (a[i] >= 0):
        a[i] = ans[j]
        j += 1

我试过了

lst = [x for (i,x) in enumerate(a) if x >= 0]

但显然我在这里误解了一些东西,因为它不起作用。

【问题讨论】:

  • ans[j] 是什么? ans 是列表吗?
  • 这里使用列表比较的主要问题是j 是有条件的高级。在理解中没有简单的方法来独立管理它。
  • @JoeFerndz 是的,这是被操纵的列表(排序),但它是一个列表
  • @Keyeric 你仍然需要以某种方式推进j。你可以定义一个函数来推进它并返回值ans[j],但此时你不妨保留代码原样
  • 列表推导式用于创建列表。你没有用你的代码创建一个列表,所以使用列表推导并不是什么有意义的事情。

标签: python python-3.x list-comprehension


【解决方案1】:

这是您的代码以及算法的解释:

j = 0                    # set the "pointer" on `ans` to the start of `ans`
for i in range(len(a)):  # for every element `e` of `a`
    if (a[i] >= 0):      # if `e` is positive
        a[i] = ans[j]    # replace it by the current element of `ans`
        j += 1           # and advance the "pointer" on `ans`.

基本上,您遍历a,当您找到一个正数时,您将其替换为ans 的下一个元素。让我们尝试一个例子:

a = [-1, 2, -3, 5, 7, -9]
ans = [10, 20, 30, 40]
 
...
         
print(a)
# [-1, 10, -3, 20, 30, -9]

如果您想使用列表推导式,您必须为a 的每个元素创建包含ans 的下一个元素(如果该元素是正数)或该元素本身的列表。然后将新列表分配给a。很简单:

a = [ans.pop(0) if e >= 0 else e for e in a]
print(a)
# [-1, 10, -3, 20, 30, -9]

显然,如果您不想消费ans,您可以使用以下命令进行复制:

temp = list(ans)
a = [e if e<0 else temp.pop(0) for e in a]

【讨论】:

    【解决方案2】:

    由于您有条件地通过ans 前进,因此您需要使用迭代器或等效的遍历机制,以避免在此过程中破坏ans(如ans.pop(0) 那样):

    ans = [-2,-4,-7]
    a   = [-1,1,-3,2,-5,-6,3,-8,-9]
    
    a   = [ n if n<0 else next(ans_j) for ans_j in [iter(ans)] for n in a]
    
    print(a)
    [-1, -2, -3, -4, -5, -6, -7, -8, -9]
    

    【讨论】:

      猜你喜欢
      • 2017-11-23
      • 1970-01-01
      • 2022-01-12
      • 2022-10-07
      • 2019-03-21
      • 2020-09-13
      • 2020-03-29
      相关资源
      最近更新 更多