在 Python 中使用列表理解避免 for 循环

Avoiding for loops using list comprehension in Python

假设我有这个 pandas.Series:

import pandas as pd
returns = pd.Series([1,2,3,4,5])

我想在上面做一些简单的数学运算,并将结果保存在一个新列表中。所以我会解释它们。 对于第一项,我要计算 returns 项的 方差

import numpy as np
def First(Ser):
    return np.var(Ser)

对于其他人,我想这样做:

def rest(variances , returns , i):
    return 0.94 * variances[i-1] + ( 1 - 0.94 ) * (returns[i-1])**2

然后使用列表理解:

variances = [rest(variances , returns , i) for i in range(len(returns)) if i!=0 else First(returns)]

但是它给了我这个错误:

variances = [rest(variances , returns , i) for i in range(len(returns)) if i!=0 else First(returns)]
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ^
SyntaxError: invalid syntax

如何避免为此目的使用 for 循环?
完整脚本:

import pandas as pd
import numpy as np

returns = pd.Series([1,2,3,4,5])

def First(Ser):
    return np.var(Ser)
    
def rest(variances , returns , i):
    return 0.94 * variances[i-1] + ( 1 - 0.94 ) * (returns[i-1])**2
    
variances = [rest(variances , returns , i) for i in range(len(returns)) if i!=0 else First(returns)]    

更多说明:

什么是 variances
variances 是我想用列表理解技术构建的列表!我想在创建时同时使用 variances我的基本目标 是避免使用 for 循环。

使用for循环的算法和预期输出:

import pandas as pd
import numpy as np

returns = pd.Series([1,2,3,4,5])
variances = []

for item in range(len(returns)):
    if item == 0:
        variances.append(np.var(returns))
    else:
        variances.append(0.94*variances[item-1] + (1-0.94)*(returns[item-1])**2)

print(variances)

[2.0, 1.94, 2.0636, 2.4797840000000004, 3.290996960000001]

您放错了 if 条件:

variances = [rest(variances , returns , i) if i!=0 else First(returns)
 for i in range(len(returns)) ]

IIUC 你可以试试 np.where:

variances = np.where(returns != 0, rest(variances , returns.tolist(), returns.index), First(returns.tolist()))

您指的是您通过列表理解创建的列表 (variances) 的第 i-1 个元素,我认为这是不可能的。但是你可以尝试这样的事情:

import pandas as pd
import numpy as np


def rest(variances , returns , i):
    if i == 0:
        variances[i] = np.var(returns)
        return variances [i]
    else:
        variances[i] = 0.94 * variances[i-1] + ( 1 - 0.94 ) * (returns[i-1])**2
        return variances [i]

returns = pd.Series([1,2,3,4,5])
placeholder = np.zeros(len(returns))

variances = [rest(placeholder , returns , i) for i in range(len(returns))]

print(variances)

# [2.0, 1.94, 2.0636, 2.4797840000000004, 3.290996960000001]

print(placeholder)

# [2.         1.94       2.0636     2.479784   3.29099696]

您不一定需要 return rest 函数中的值,因为该函数的实际目的是更新现有的 placeholder 列表。但是,如果您的函数没有 return 任何内容,则列表理解将 return 一个包含 None 个值的列表。