Python中列表元素打印及嵌套数据类型处理问题
列表元素重复打印的原因与解决方法
问题背景
要打印以下列表的每个元素:
l=[7, ['one', 'two', 'three'], (1, 2), 6, ('a',), {'set1', 'set2'}, 5.4, [None]]
期望输出:
list [ 0 ] = 7 list [ 1 ] [ 0 ] = one list [ 1 ] [ 1 ] = two list [ 1 ] [ 2 ] = three list [ 2 ] [ 0 ] = 1 list [ 2 ] [ 1 ] = 2 list [ 3 ] = 6 list [ 4 ] [ 0 ] = a list [ 5 ] = {'set1', 'set2'} list [ 6 ] = 5.4 list [ 7 ] [ 0 ] = None
编写的代码:
def PrintListElements(list): for i in range(len(list)): try: for j in range(len(list[i])): print('list', '[', i, ']', '[', j, ']', '=', list[i][j]) except TypeError: print('list', '[', i, ']', '=', list[i]) else: print('list', '[', i, ']', '[', j, ']', '=', list[i][j]) PrintListElements(l)
实际输出中,可索引类型(列表、元组)的最后一个元素被重复打印:
list [ 0 ] = 7 list [ 1 ] [ 0 ] = one list [ 1 ] [ 1 ] = two list [ 1 ] [ 2 ] = three list [ 1 ] [ 2 ] = three list [ 2 ] [ 0 ] = 1 list [ 2 ] [ 1 ] = 2 list [ 2 ] [ 1 ] = 2 list [ 3 ] = 6 list [ 4 ] [ 0 ] = a list [ 4 ] [ 0 ] = a list [ 5 ] = {'set1', 'set2'} list [ 6 ] = 5.4 list [ 7 ] [ 0 ] = None list [ 7 ] [ 0 ] = None
问题原因
问题出在try-except-else的逻辑上:
- 当
try块内的代码没有抛出异常时,else块会被执行。 - 对于可索引的元素(列表、元组),内层
for循环已经完整打印了所有元素,循环结束后j保留最后一个索引值。此时else块再次执行print语句,就会把最后一个元素重复打印一次。
比如处理list[1]时,内层循环打印了索引0、1、2的元素,循环结束后j=2,else块又执行print('list [ 1 ] [ 2 ] = three'),导致重复。
解决方案
方案1:移除多余的else块
直接删除else部分,因为内层for循环已经完成了所有可索引元素的打印,不需要额外的输出:
def PrintListElements(input_list): # 避免用list作为参数名,覆盖内置类型 for i in range(len(input_list)): try: for j in range(len(input_list[i])): print(f'list [ {i} ] [ {j} ] = {input_list[i][j]}') # 用f-string更简洁 except TypeError: print(f'list [ {i} ] = {input_list[i]}') l = [7, ['one', 'two', 'three'], (1, 2), 6, ('a',), {'set1', 'set2'}, 5.4, [None]] PrintListElements(l)
方案2:提前判断元素类型(更严谨)
如果想避免依赖异常捕获,可以提前判断元素是否是可索引且非集合的类型(集合不可索引):
def PrintListElements(input_list): for idx, elem in enumerate(input_list): # 判断是否是可索引的序列类型(列表、元组,排除集合) if isinstance(elem, (list, tuple)): for sub_idx, sub_elem in enumerate(elem): print(f'list [ {idx} ] [ {sub_idx} ] = {sub_elem}') else: print(f'list [ {idx} ] = {elem}') l = [7, ['one', 'two', 'three'], (1, 2), 6, ('a',), {'set1', 'set2'}, 5.4, [None]] PrintListElements(l)
这两种方案都能得到符合预期的输出,方案2更直观,避免了异常捕获的开销,同时明确区分了需要递归打印的类型。
内容的提问来源于stack exchange,提问作者Popsicle
相关产品推荐
相关产品推荐

