为何Python中需两次调用函数才能完成指定类别产品排序?如何优化?
问题:为何需两次调用函数才能将指定类别产品移至列表前端?
原始数据与当前代码
原始产品列表与目标类别:
products =[{'t1': 'bbq', 'category': 2}, {'name': 't5', 'category': 3}, {'name': 't6', 'category': 3}, {'name': 't2', 'category': 2}, {'name': 't3', 'category': 2}, {'name': 't4', 'category': 1}, {'name': 't7', 'category': 1}] category = 2
当前实现函数:
def sort_by_cat(products,category): for p in products: print(p) if p['category']==category: continue else: products.append(products.pop(products.index(p))) return sort_by_cat(products,category) sort_by_cat(products,category)
现象:必须连续调用两次函数,才能将所有category=2的产品移至列表前端,得到期望输出:
[{'t1': 'bbq', 'category': 2}, {'name': 't2', 'category': 2}, {'name': 't3', 'category': 2}, {'name': 't4', 'category': 1}, {'name': 't5', 'category': 3}, {'name': 't6', 'category': 3}, {'name': 't7', 'category': 1}]
原因分析
原函数的问题出在遍历方式:
- 直接
for p in products时,迭代器基于列表初始状态生成,遍历过程中修改列表(如将元素移到末尾),迭代器不会重新扫描新添加到末尾的元素。 - 第一次调用仅能处理原列表中位于目标元素之前的非目标元素;原本在目标元素之后的非目标元素,会被第一次迭代的指针跳过,无法被处理。第二次调用时,这些未处理的元素才会被遍历到并移到末尾,最终得到正确结果。
修改方案(一次调用完成,原地修改)
方案1:遍历列表的副本
通过遍历原列表的拷贝,确保所有初始元素都被检查,不受列表实时修改的影响:
def sort_by_cat(products, category): # 遍历原列表的副本,避免迭代过程中列表变化干扰遍历 for p in list(products): if p['category'] != category: idx = products.index(p) products.append(products.pop(idx))
方案2:固定遍历次数(原列表长度)
循环原列表长度的次数,每次检查第一个元素,非目标类别则移到末尾,确保所有元素都被处理:
def sort_by_cat(products, category): # 循环原列表长度次,确保每个元素都被检查 for _ in range(len(products)): first_item = products[0] if first_item['category'] != category: products.append(products.pop(0))
两种方案都能实现原地修改,且仅需调用一次sort_by_cat(products, category)即可得到期望结果。
内容的提问来源于stack exchange,提问作者Mark McGown
相关产品推荐
相关产品推荐

