影刀RPA 集合Set的使用:去重与集合运算

影刀RPA 集合Set的使用:去重与集合运算 影刀RPA 集合Set的使用去重与集合运算作者林焱什么情况用你在采集商品数据时多个页面有重复商品需要快速去重你想找出这次采集到的和上次采集到的之间的差异——哪些是新增的哪些是消失的你有两个名单需要取交集列表虽然也能去重但数据量大了速度慢得让人抓狂。**集合Set**就是为这类场景而生的——天然去重、查找极快、支持交集/并集/差集运算。本文讲清楚影刀RPA中什么时候用Set、怎么用、和列表怎么互转。怎么做一、集合的基本特性特性说明对比列表元素唯一自动去重列表允许重复无序没有索引不能按位置访问列表有序查找极快in操作O(1)列表in是O(n)| 可变 | 可以添加删除元素 | 列表也可变 || 元素必须可哈希 | 只能放int/str/tuple不能放list/dict | 列表什么都能放 |二、创建集合# 直接创建fruits{apple,banana,orange}numbers{1,2,3,4,5}# 从列表创建自动去重raw_list[1,2,2,3,3,3,4,4,4,4]unique_setset(raw_list)# {1, 2, 3, 4}# 从字符串创建获取所有字符charsset(hello world)# {h, e, l, o, , w, r, d}# 空集合注意不能用{}那是空字典empty_setset()三、集合的增删拼多多店群自动化上架方案data{1,2,3}# 添加单个元素data.add(4)# {1, 2, 3, 4}data.add(2)# {1, 2, 3, 4} - 已存在不重复添加# 添加多个元素data.update([5,6])# {1, 2, 3, 4, 5, 6}data.update({7,8})# {1, 2, 3, 4, 5, 6, 7, 8}![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/cd7c3e7d76b54cd7b71c4b35d40f9d46.png#pic_center)# 删除元素data.remove(8)# {1, 2, 3, 4, 5, 6, 7} - 不存在会报错data.discard(100)# 不存在也不报错安全删除data.pop()# 随机删除一个元素集合无序data.clear()# 清空集合四、集合运算核心功能set_a{1,2,3,4,5}set_b{4,5,6,7,8}# 交集两个集合都有的元素intersectionset_aset_b# {4, 5}# 等价写法intersectionset_a.intersection(set_b)# 并集两个集合的所有元素自动去重unionset_a|set_b# {1, 2, 3, 4, 5, 6, 7, 8}# 等价写法unionset_a.union(set_b)# 差集在A中但不在B中的元素differenceset_a-set_b# {1, 2, 3}# 等价写法differenceset_a.difference(set_b)# 对称差集只在其中一个集合中出现的元素symmetricset_a^set_b# {1, 2, 3, 6, 7, 8}# 等价写法symmetricset_a.symmetric_difference(set_b)# 子集判断{1,2}.issubset({1,2,3})# True# 超集判断{1,2,3}.issuperset({1,2})# True# 无交集判断{1,2}.isdisjoint({3,4})# True五、RPA实战场景场景1多页采集去重# 采集多个页面的商品ID跨页去重all_idsset()# 用集合存储自动去重forpageinrange(1,11):# 模拟采集每页的商品ID列表page_idsyd_var[fpage_{page}_ids]# 假设是列表 [P001, P002, ...]# 添加到集合自动去重all_ids.update(page_ids)print(f第{page}页: 本页{len(page_ids)}个累计{len(all_ids)}个唯一)yd_var[unique_ids]list(all_ids)# 转回列表存储print(f去重后共{len(all_ids)}个商品)场景2找出新增和消失的数据# 今天的采集结果today_data{P001,P002,P003,P004,P005}# 昨天的采集结果从文件读取yesterday_data{P001,P002,P006,P007}# 新增的商品今天有昨天没有new_itemstoday_data-yesterday_data# {P003, P004, P005}# 消失的商品昨天有今天没有removed_itemsyesterday_data-today_data# {P006, P007}# 不变的商品unchangedtoday_datayesterday_data# {P001, P002}yd_var[new_items]list(new_items)yd_var[removed_items]list(removed_items)yd_var[unchanged]list(unchanged)场景3黑名单过滤# 已采集的URL列表urls[https://example.com/page1,https://example.com/page2,https://example.com/page3,https://example.com/page1,# 重复https://example.com/page4,]# 黑名单域名集合blacklist{example.com/blocked,spam.com}# 过滤不在黑名单中且去重filtered_urls[]seenset()forurlinurls:ifurlnotinseen:seen.add(url)is_blockedany(blockinurlforblockinblacklist)ifnotis_blocked:filtered_urls.append(url)print(filtered_urls)# [https://example.com/page1, https://example.com/page2,# https://example.com/page3, https://example.com/page4]场景4两个Excel名单比对importopenpyxl# 读取第一个Excel的ID列wb1openpyxl.load_workbook(名单A.xlsx)ws1wb1.active set_aset()forrowinws1.iter_rows(min_row2,min_col1,max_col1,values_onlyTrue):ifrow[0]:set_a.add(str(row[0]).strip())# 读取第二个Excel的ID列wb2openpyxl.load_workbook(名单B.xlsx)ws2wb2.active set_bset()forrowinws2.iter_rows(min_row2,min_col1,max_col1,values_onlyTrue):![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/dd218c05c5024f469e88b2192b3f2f14.png#pic_center)ifrow[0]:set_b.add(str(row[0]).strip())# 比对结果only_in_aset_a-set_b# 只在A中的only_in_bset_b-set_a# 只在B中的in_bothset_aset_b# 两个都有的all_uniqueset_a|set_b# 合并去重print(fA独有:{len(only_in_a)})print(fB独有:{len(only_in_b)})print(f共有:{len(in_both)})print(f合并去重:{len(all_unique)})场景5标签匹配# 商品标签product_tags{商品A:{手机,电子,苹果},商品B:{电脑,电子,戴尔},商品C:{手机,配件,华为},}# 用户感兴趣的标签user_interests{手机,苹果}# 找出包含用户任一兴趣标签的商品matched[]forproduct,tagsinproduct_tags.items():iftagsuser_interests:# 交集不为空matched.append(product)print(matched)# [商品A, 商品C]# 找出同时包含所有兴趣标签的商品fully_matched[]forproduct,tagsinproduct_tags.items():ifuser_interests.issubset(tags):# 用户兴趣是商品标签的子集fully_matched.append(product)print(fully_matched)# [商品A]六、集合与列表的互转# 列表 → 集合去重my_list[1,2,2,3,3,3]my_setset(my_list)# {1, 2, 3}# 集合 → 列表my_listlist(my_set)# [1, 2, 3]顺序不保证# 集合 → 排序列表sorted_listsorted(my_set)# [1, 2, 3]排序后顺序确定# 保持原顺序去重集合列表配合raw[3,1,2,3,1,4,2]seenset()unique_ordered[]foriteminraw:ifitemnotinseen:seen.add(item)unique_ordered.append(item)print(unique_ordered)# [3, 1, 2, 4] - 保持首次出现的顺序有什么坑坑1集合是无序的不能按索引访问现象my_set[0]报错TypeError: set object is not subscriptable。原因集合没有顺序概念不支持索引访问。解决如果需要按顺序访问先转成排序列表sorted_list sorted(my_set)。如果只需要遍历直接for item in my_set:即可但每次遍历的顺序可能不同。坑2集合里不能放列表或字典现象{[1, 2], [3, 4]}报错TypeError: unhashable type: list。原因集合元素必须是可哈希的immutable列表和字典是可变的不能哈希。TEMU店群如何管理运营解决把列表转成元组再放集合{(1, 2), (3, 4)}。字典转成元组{(key1, val1), (key2, val2)}。或者用字符串序列化。坑3集合转列表后顺序不确定现象list({3, 1, 2})的结果可能是[1, 2, 3]也可能是[2, 1, 3]每次运行可能不同。原因集合的内部存储顺序由哈希值决定不同Python版本或不同运行环境可能不同。解决如果顺序重要转列表后用sorted()排序。或者使用保持顺序去重的模式见上文代码不依赖集合的遍历顺序。坑4大集合运算的内存问题现象两个各100万元素的集合做交集内存暴涨。原因集合运算会创建新的集合对象同时占用原集合和新集合的内存。解决用intersection_update等就地运算方法直接在原集合上修改不创建新对象# 创建新集合内存翻倍resultset_aset_b# 就地修改省内存set_a.intersection_update(set_b)# set_a被修改为交集坑5影刀变量中存储集合现象把集合直接赋给影刀变量后续读取时变成了列表或者报错。原因影刀变量系统可能不完全支持Set类型序列化/反序列化时会转成列表。解决在Python代码块内部使用集合完成运算然后把结果转成列表再存入影刀变量yd_var[result] list(my_set)。需要再次使用时在Python代码块中重新set(yd_var[result])。