Python中避免生成器方法及绘图float与generator相乘报错排查
问题解答:TypeError 错误分析与修复,以及Python中避免生成器的方法
一、TypeError: unsupported operand type(s) for *: 'float' and 'generator' 的原因与解决方法
错误来源
看你的代码,核心问题出在这一行:
plt.plot([-10,-9,-8,-7,-6,-5,-4,-3,-2,-1],[C(i for i in range (-10,-1))])
你把生成器表达式 i for i in range (-10,-1) 直接传给了lambda函数C,但C的设计是接收单个数值ksi来做数学计算。当生成器传入后,lambda里执行((u-w * sigma)/v)*ksi时,相当于用浮点数去乘一个生成器对象——Python根本不允许这种操作,所以触发了类型错误。
另外还有两个小细节需要修复:
plt.xlabel(ksi)和plt.ylabel(concentration)里的ksi、concentration是字符串标签,必须加引号,否则会被当作变量查找,引发NameError。- 你的
sigma变量在for i in range(1,10)循环里重复赋值,循环结束后sigma只会保留最后一次的计算结果,如果你需要每次循环的sigma都参与绘图,可能还要调整逻辑,但先解决当前的报错问题。
修复后的代码
把生成器表达式换成列表推导式,让C函数逐个接收每个x值,生成对应的结果列表:
from math import * import matplotlib.pyplot as plt t = 0.1 cd = t * exp(-t/2) tau = 10 nt = 100 v = 0.01 w = 0.9 u = 0.4 s0 = 10 p = 5 # 循环计算sigma,保留你原本的逻辑(注意sigma最终是最后一次循环的结果) for i in range(1, 10): sigma = u / (w + (s0 / (p * cd))) print(sigma) # 定义C函数,接收单个数值ksi C = lambda ksi: cd * (1 - exp(((u - w * sigma)/v) * ksi)) # 用列表推导式生成每个x对应的y值列表 x_values = [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1] y_values = [C(x) for x in x_values] plt.plot(x_values, y_values) plt.xlabel("ksi") # 给标签加引号 plt.ylabel("concentration") # 给标签加引号 plt.title("tumeur avec regénessence") plt.legend() plt.show() t += tau / nt
二、如何在Python中避免使用生成器
生成器是Python的实用特性,但不小心误用会引发问题,以下是几个避免意外使用生成器的技巧:
- 分清生成器表达式和列表推导式:生成器表达式是
(x for x in iterable),列表推导式是[x for x in iterable]。如果需要完整序列(比如传给需要列表的函数、要随机访问元素),就用列表推导式,别用生成器。 - 不要给需要单个值的函数传生成器:比如你的案例中,
C需要单个数值,就不能直接传生成器,要逐个传入元素或用列表推导式批量生成结果。 - 显式转换为列表:如果不确定生成器是否合适,用
list()把它转换成列表,比如list(x for x in range(10)),这样就能获得一个可重复遍历、可索引的序列。 - 注意函数参数里的隐式生成器:如果在函数参数里直接写
func(x for x in ...),这就是生成器;要传列表的话,必须写成func([x for x in ...])或者func(list(x for x in ...))。 - 用for循环显式迭代:如果对生成器的使用存疑,可以用for循环逐个处理元素,把结果存入列表后再使用这个列表,这样更直观也不容易出错。
内容的提问来源于stack exchange,提问作者ilyes abidi
相关产品推荐
相关产品推荐

