Python2.7如何用单行代码实现元组列表焦点标记顺时针循环切换
问题描述
需要对元组列表中的单个元组焦点标记进行顺时针循环切换:当焦点标记位于列表最后一个元组上时,下一次切换需回到列表首个元组。
现有数据结构示例
x = [] x.append(('search','https://www.search.com','1')) # '1' 代表当前焦点 x.append(('financials','https://www.stock-exchange.com','0')) x.append(('fastfood','https://www.burgers.com','0')) x.append(('tv','https://www.tv.com','0')) print x # 输出结果 [('search','https://www.search.com','1'),('financials','https://www.stock-exchange.com','0'),('fastfood','https://www.burgers.com','0'),('tv','https://www.tv.com','0')]
预期效果
初始焦点状态:
- - * - - - - - -
切换到下一行后:
- - - - * - - - -
依此类推,到最后一行后切回第一行循环。
当前已实现代码
定位焦点单行代码
a,b,c = list(data[[index for (index, a_tuple) in enumerate(x) if a_tuple[2]=='1'][0]])
焦点切换代码(逻辑可行但冗长)
newX = [] # 创建新列表存储修改后的元组 if '1' in x[len(x)-1][2]: # 判断焦点是否在最后一个元组,是则切回第一个 for b in range(0,len(x),1): # 遍历所有元组 if b == 0: # 给第一个元组设置焦点 newX.append((x[b][0],x[b][1],'1')) # 写入新列表 else: # 其他元组取消焦点 newX.append((x[b][0],x[b][1],"0")) # 写入新列表 else: # 焦点不在末尾,先找当前焦点位置 a = 0 # 存储当前焦点索引 for b in range(0,len(x),1): # 遍历找焦点 if '1' in x[b][2]: # 找到焦点 a = b # 记录索引 break # 找到就停止遍历 for b in range(0,len(x),1): # 再次遍历设置新焦点 if b == a+1: # 给下一个元组设置焦点 newX.append((x[b][0],x[b][1],'1')) # 写入新列表 else: # 其他元组取消焦点 newX.append((x[b][0],x[b][1],"0")) # 写入新列表 x = newX # 覆盖原列表 del newX,a,b # 清理临时变量节省内存
需求
当前使用Python2.7版本,希望用更简洁的方式甚至单行代码实现上述焦点切换功能,有没有对应的内置功能或者更优的实现方案?
解决方案
兼容Python2.7的单行实现
x = [(t[0], t[1], '1') if i == (next(idx for idx, val in enumerate(x) if val[2] == '1') + 1) % len(x) else (t[0], t[1], '0') for i, t in enumerate(x)]
实现逻辑说明
- 用
next(idx for idx, val in enumerate(x) if val[2] == '1')查找当前焦点索引,比列表推导取首元素效率更高,找到第一个匹配项就会停止遍历 - 用
(当前焦点索引 + 1) % 列表长度计算下一个焦点的索引,天然支持最后一位切回第一位的循环逻辑,不需要额外的边界判断 - 用列表推导一次性生成新的元组列表,对应下一个焦点索引的元组标记设为'1',其余统一设为'0'
如果觉得单行可读性不佳,也可以拆分为两行更易维护:
cur_idx = next(idx for idx, val in enumerate(x) if val[2] == '1') x = [(t[0], t[1], '1' if i == (cur_idx + 1) % len(x) else '0') for i, t in enumerate(x)]
内容的提问来源于stack exchange,提问作者User100
相关产品推荐
相关产品推荐

