如何将指定格式的房屋-用户映射字典转换为目标结构数组以实现批量发信?
解决思路与实现代码
嘿,这个需求本质上就是反向映射+分组聚合——把原来「房屋ID→用户ID列表」的对应关系,转换成「共享同一批房屋的用户组→房屋ID列表」,最终整理成你需要的数组格式,从而减少批量发送请求的次数。
具体步骤
- 反向映射:先建立「用户ID→包含该用户的房屋ID集合」的映射,这样能知道每个用户需要关联哪些房屋;
- 分组聚合:把关联同一批房屋的用户归为一组,也就是构建「房屋ID集合→用户ID列表」的映射;
- 格式转换:把上面的映射转换成你要求的字典数组格式。
Python 实现代码
基础版本(无需额外库)
items_dict = {123: [1, 2, 3], 456: [1, 2, 3, 4], 678: [1, 2]} # 1. 构建用户ID到房屋ID集合的映射 user_to_items = {} for item_id, user_ids in items_dict.items(): for user_id in user_ids: if user_id not in user_to_items: user_to_items[user_id] = set() user_to_items[user_id].add(item_id) # 2. 反转映射,将共享同一批房屋的用户分组 item_group_to_users = {} for user_id, item_ids in user_to_items.items(): # 用排序后的元组作为键(集合不可哈希,不能当字典键) item_key = tuple(sorted(item_ids)) if item_key not in item_group_to_users: item_group_to_users[item_key] = [] item_group_to_users[item_key].append(user_id) # 3. 转换成目标数组格式 result = [] for item_ids, user_ids in item_group_to_users.items(): result.append({ 'item_ids': list(item_ids), 'users_ids': sorted(user_ids) # 排序可选,根据需求调整 }) print(result) # 输出:[{'item_ids': [123, 456], 'users_ids': [3]}, {'item_ids': [456], 'users_ids': [4]}, {'item_ids': [123, 456, 678], 'users_ids': [1, 2]}]
简化版本(使用collections.defaultdict)
如果不想写太多判断逻辑,可以用Python标准库的defaultdict来简化代码:
from collections import defaultdict items_dict = {123: [1, 2, 3], 456: [1, 2, 3, 4], 678: [1, 2]} # 1. 反向映射 user_to_items = defaultdict(set) for item_id, user_ids in items_dict.items(): for user_id in user_ids: user_to_items[user_id].add(item_id) # 2. 分组聚合 item_group_to_users = defaultdict(list) for user_id, item_ids in user_to_items.items(): item_key = tuple(sorted(item_ids)) item_group_to_users[item_key].append(user_id) # 3. 格式转换 result = [{'item_ids': list(k), 'users_ids': sorted(v)} for k, v in item_group_to_users.items()] print(result)
关键细节说明
- 使用集合存储房屋ID:避免同一房屋ID被重复添加到同一个用户的关联列表中;
- 用排序后的元组作为字典键:因为集合是可变类型,不能作为字典的键,转换成排序后的元组可以保证相同的房屋集合(不管顺序)会被识别为同一个分组键;
- 排序用户ID:可选操作,如果你的业务不需要有序的用户ID列表,可以去掉
sorted(),提升一点性能。
内容的提问来源于stack exchange,提问作者Dmitri Kalbfleysh
相关产品推荐
相关产品推荐

