(译)Python’s lambda is broken!(Python的lambda坏了!)

本文通过一个具体的例子揭示了Python中使用lambda表达式时容易遇到的问题,即闭包捕获变量的实际行为与预期不符的情况,并提供了几种解决该问题的有效方法。
[url]http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/[/url]


[size=medium][align=center]Python"s lambda is broken![/align][/size]
[size=medium][align=center]Python的lambda坏了![/align][/size]

我很喜欢用Python来教学,并且人们赞美lambda的够造—它像一个抽象的函数式语言,但是,它有时出错!

来看看lambda是怎么出错的把,构造一个list,list里包含函数`fs = [f_0, ..., f_9]` ,并且我们想让函数是这样的`f_i(n) = i + n`。一开始我们试图这样写:


>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13


等一下,f[3](4)应该是3+4 = 7!这看起来像10个函数用了一个最后一个i的值---9,事实上


>>> [f(4) for f in fs]
[13, 13, 13, 13, 13, 13, 13, 13, 13, 13]


这肯定不对,让我们不用lambda试试:


>>> fs = []
>>> for i in range(10):
... def f(n): return i+n
... fs.append(f)
...
>>> [f(4) for f in fs]
[13, 13, 13, 13, 13, 13, 13, 13, 13, 13]


它仍然不对,深想一下,可能是环境不对,可能应该这样:

>>> fs = []
>>> for i in range(10):
... def f(n, i=i): return i+n
... fs.append(f)
...
>>> [f(4) for f in fs]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]


胜利!但是我试图想学生们解释这是为什么。
只是很确定地,Haskell却能够实现

Prelude> let fs = [(\n -> i + n) | i <- [0..9]]
Prelude> [f(4) | f <- fs]
[4,5,6,7,8,9,10,11,12,13]

Python的解释器在想什么?!


楼下mcmanus给出了个很好的解释:


>>> i = 1
>>> def f(): return i
>>> f()
1
>>> i = 2
>>> f()
2



楼下roberto又给出了个解决方案:


>>> fs = [(lambda n, i=i: i + n) for i in range(10)]



楼下tim finin的方法

>>> def def_f(i):
return lambda n: i + n
>>> fs = [def_f(i) for i in range(10)]
>>> fs[3](4)
7



Kamran的

fs= map(lambda i:lambda n: i + n, range(10))
关于 阿里云盘CLI。仿 Linux shell 文件处理命令的阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能,支持相册批量下载。 特色 多平台支持, 支持 Windows, macOS, linux(x86/x64/arm), android, iOS 等 阿里云盘多用户支持 支持备份盘,资源库无缝切换 下载网盘内文件, 支持多个文件或目录下载, 支持断点续传和单文件并行下载。支持软链接(符号链接)文件。 上传本地文件, 支持多个文件或目录上传,支持排除指定文件夹/文件(正则表达式)功能。支持软链接(符号链接)文件。 同步备份功能支持备份本地文件到云盘,备份云盘文件到本地,双向同步备份保持本地文件和网盘文件同步。常用于嵌入式或者NAS等设备,支持docker镜像部署。 命令和文件路径输入支持Tab键自动补全,路径支持通配符匹配模式 支持JavaScript插件,你可以按照自己的需要定制上传/下载中关键步骤的行为,最大程度满足自己的个性化需求 支持共享相册的相关操作,支持批量下载相册所有普通照片、实况照片文件到本地 支持多用户联合下载功能,对下载速度有极致追求的用户可以尝试使用该选项。详情请查看文档多用户联合下载 如果大家有打算开通阿里云盘VIP会员,可以使用阿里云盘APP扫描下面的优惠推荐码进行开通。 注意:您需要开通【三方应用权益包】,这样使用本程序下载才能加速,否则下载无法提速。 Windows不第二步打开aliyunpan命令行程序,任何云盘命令都有类似如下日志输出 如何登出和下线客户端 阿里云盘单账户最多只允许同时登录 10 台设备 当出现这个提示:你账号已超出最大登录设备数量,请先下线一台设备,然后重启本应用,才可以继续使用 说明你的账号登录客户端已经超过数量,你需要先登出其他客户端才能继续使用,如下所示
### 使用Python和OpenCV实现简单车牌识别 #### 准备开发环境 为了顺利运行车牌识别程序,需准备如下软件包: - Python版本应不低于3.8.5。 - OpenCV-Python库用于图像处理操作,建议版本为4.5以上。 - Matplotlib辅助展示中间结果图象,推荐使用最新稳定版如3.5.0。 - Tesseract-OCR负责文字识别部分,确保已正确安装并配置至系统路径中[^1]。 ```bash pip install numpy matplotlib opencv-python pytesseract scikit-learn joblib ``` #### 加载与预览输入图片 通过读取待检测车辆照片作为算法起点,利用`cv2.imread()`函数加载本地存储的图像文件,并调用`plt.imshow()`显示原始彩色图像以便观察。 ```python import cv2 from matplotlib import pyplot as plt def show_image(img, title="Image"): """Helper function to display an image.""" plt.figure(figsize=(10, 7)) plt.axis('off') plt.title(title) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # Convert BGR to RGB for correct color representation. plt.show() image_path = 'car_plate.jpg' original_img = cv2.imread(image_path) show_image(original_img, "Original Image") ``` #### 图像预处理阶段 针对获取到的真实世界中的复杂背景情况,采取灰度化、高斯模糊以及边缘增强等一系列手段来简化后续特征提取过程。这些措施有助于提高最终定位精度的同时减少误判率。 ```python gray_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY) # Grayscale conversion. blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0) # Gaussian blur reduces noise while preserving edges. edged_img = cv2.Canny(blurred_img, 30, 200) # Edge detection using Canny algorithm. show_image(edged_img, "Edged Image") # Display processed edge-detected result. ``` #### 车牌区域轮廓查找 基于上述得到的二值化边界信息,在此基础上应用形态学变换(膨胀腐蚀),并通过`findContours()`方法找出所有封闭形状,再从中筛选出最有可能属于车牌范围内的矩形框体结构。 ```python dilated_img = cv2.dilate(edged_img, None, iterations=2) # Dilate the edged image slightly to connect broken parts of contours. contours, _ = cv2.findContours(dilated_img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:] sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] plate_candidates = [] for contour in sorted_contours: perimeter = cv2.arcLength(contour, True) approximated_shape = cv2.approxPolyDP(contour, 0.02 * perimeter, True) if len(approximated_shape) == 4: # Assuming license plates are quadrilateral shapes. plate_candidates.append(approximated_shape) if not plate_candidates: raise Exception("No potential license plate found.") # Draw bounding boxes around detected candidates on a copy of original image. boxed_img = original_img.copy() for candidate in plate_candidates: x, y, w, h = cv2.boundingRect(candidate) cv2.rectangle(boxed_img, (x,y),(x+w,y+h),(0,255,0),2) show_image(boxed_img, "Detected Plate Candidates") ``` #### 文字识别环节 当成功锁定目标位置之后,则可以截取出该子区域送入Tesseract引擎完成字符解析工作;在此之前还需做必要的颜色空间转换以适应不同光照条件下的实际应用场景需求。 ```python selected_candidate = max(plate_candidates, key=lambda c: cv2.boundingRect(c)[2]*cv2.boundingRect(c)[3]) x, y, width, height = cv2.boundingRect(selected_candidate) cropped_license_plate = gray_img[y:y + height, x:x + width] _, thresholded_lp = cv2.threshold(cropped_license_plate, 150, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) text = pytesseract.image_to_string(thresholded_lp, lang='eng') print(f"Recognized Text: {text.strip()}") show_image(thresholded_lp, f"Thresholded License Plate ({text})") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值