如何让内循环在外循环完成后最后一次触发

我有两个清单:

  • 第一个列表包含顶级名称信息;每个项目有多个描述符

  • 第二个列表包含第一个列表中项目的变体;每个项目还有多个描述符

外部(第一个)列表包含三项;name1name2、 和name3。还有一个source,但我没有费心在示例中更改它以保持简单。

内部(第二个)列表包含外部列表的名称和来源,然后有自己的名称和来源。

最终结果应该是这样的:

name1 (source1)

===============

* [name1-foo1]: . "description1"

* [name1-foo2]: . "description2"

* [name1-foo3]: . "description3"


subname1 (subsource1)

---------------

* [name1-sub1-bar1]: . "description1"

* [name1-sub1-bar2]: . "description2"

* [name1-sub1-bar3]: . "description3"


subname2 (subsource1)

---------------

* [name1-sub2-bar1]: . "description1"

* [name1-sub2-bar2]: . "description2"

* [name1-sub2-bar3]: . "description3"


...

我的问题是我的外循环查找name和中的更改source作为打印标题并继续打印下一个内容的触发器。但由于内循环仅由更改触发,因此当外循环运行完时,它不会最后一次运行内循环来获取所有子项。


import collections


OuterRecord = collections.namedtuple('OuterRecord',

                                     'name, source, thing, level, description')

InnerRecord = collections.namedtuple('InnerRecord',

                                     'name, source, in_name, in_source, thing, level, description')


o = [

    OuterRecord('name1', 'source1', 'name1-foo1', 1, 'description1'),

    OuterRecord('name1', 'source1', 'name1-foo2', 5, 'description2'),

    OuterRecord('name1', 'source1', 'name1-foo3', 10, 'description3'),


    OuterRecord('name2', 'source1', 'name2-foo1', 1, 'description1'),

    OuterRecord('name2', 'source1', 'name2-foo2', 5, 'description2'),

    OuterRecord('name2', 'source1', 'name2-foo3', 10, 'description3'),


    OuterRecord('name3', 'source1', 'name3-foo1', 1, 'description1'),

    OuterRecord('name3', 'source1', 'name3-foo2', 5, 'description2')

]

]

因此,一旦一切完成,我可以再次单独运行内部循环,但这闻起来很糟糕。


有没有更好的方法来构建循环,以便这一切一次性发生?


肥皂起泡泡
浏览 125回答 2
2回答

jeck猫

您的代码的一个有趣的事实是,它看起来具有检测更改背后的价值。不幸的是,最后一个值没有机会被检测到,因为循环在那里结束。相反,使用两个指针,一个用于当前值,一个用于列表中的下一个值。使用这样的条件来检测下一个的变化(lookahead)for index, outer in enumerate(outer_list):&nbsp; &nbsp; next_outer_source = outer_list[index + 1] if index < len(outer_list) - 1 else None&nbsp; &nbsp; show_outer_header = current_outer_name != outer.name or current_outer_source != outer.source&nbsp; &nbsp; show_inner_values = next_outer_source is None or outer.name != next_outer_source.name or outer.source != next_outer_source.source&nbsp;这是您的函数的清理副本:def loop_over(outer_list, inner_list):&nbsp; &nbsp; current_outer_name = None&nbsp; &nbsp; current_outer_source = None&nbsp; &nbsp; current_inner_name = None&nbsp; &nbsp; current_inner_source = None&nbsp; &nbsp; prev_outer_source = None&nbsp; &nbsp; for index, outer in enumerate(outer_list):&nbsp; &nbsp; &nbsp; &nbsp; next_outer_source = outer_list[index + 1] if index < len(outer_list) - 1 else None&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; show_outer_header = current_outer_name != outer.name or current_outer_source != outer.source&nbsp; &nbsp; &nbsp; &nbsp; show_inner_values = next_outer_source is None or outer.name != next_outer_source.name or outer.source != next_outer_source.source&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # print outer header&nbsp; &nbsp; &nbsp; &nbsp; if show_outer_header:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('\n{} ({})'.format(outer.name, outer.source))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('=' * 15)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_outer_name, current_outer_source = outer.name, outer.source&nbsp; &nbsp; &nbsp; &nbsp; # print outer value&nbsp; &nbsp; &nbsp; &nbsp; print('* [{}]: . "{}"'.format(outer.thing, outer.description))&nbsp; &nbsp; &nbsp; &nbsp; # print inner values&nbsp; &nbsp; &nbsp; &nbsp; if show_inner_values:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_outer_name = outer.name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_outer_source = outer.source&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for inner in [x for x in inner_list if x.name == current_outer_name and x.source == current_outer_source]:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if current_inner_name is None:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('\n{} ({})'.format(inner.in_name, inner.in_source))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('-' * 15)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_inner_name = inner.in_name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_inner_source = inner.in_source&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if inner.in_name != current_inner_name or inner.in_source != current_inner_source:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('\n{} ({})'.format(inner.in_name, inner.in_source))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('-' * 15)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_inner_name = inner.in_name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current_inner_source = inner.in_source&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('* [{}]: . "{}"'.format(inner.thing, inner.description))输出:name1 (source1)===============* [name1-foo1]: . "description1"* [name1-foo2]: . "description2"* [name1-foo3]: . "description3"subname1 (subsource1)---------------* [name1-sub1-bar1]: . "description1"* [name1-sub1-bar2]: . "description2"* [name1-sub1-bar3]: . "description3"subname2 (subsource1)---------------* [name1-sub2-bar1]: . "description1"* [name1-sub2-bar2]: . "description2"* [name1-sub2-bar3]: . "description3"name2 (source1)===============* [name2-foo1]: . "description1"* [name2-foo2]: . "description2"* [name2-foo3]: . "description3"subname3 (subsource1)---------------* [name2-sub3-bar1]: . "description1"* [name2-sub3-bar2]: . "description2"* [name2-sub3-bar2]: . "description3"name3 (source1)===============* [name3-foo1]: . "description1"* [name3-foo2]: . "description2"subname4 (subsource1)---------------* [name3-sub4-bar1]: . "description1"* [name3-sub4-bar2]: . "description2"* [name3-sub4-bar2]: . "description3"subname5 (subsource1)---------------* [name3-sub5-bar1]: . "description1"* [name3-sub5-bar2]: . "description2"* [name3-sub5-bar3]: . "description3"subname6 (subsource1)---------------* [name3-sub6-bar1]: . "description1"* [name3-sub6-bar2]: . "description2"* [name3-sub6-bar3]: . "description3"

慕标琳琳

考虑到详细的数据结构,我预计效率并不是您真正追求的,因此这似乎是一种相当简洁且可读的方式来获取您所需要的内容:def print_outer_and_inner(outer_recs, inner_recs):&nbsp; &nbsp; for name, source in {(o_rec.name, o_rec.source): None for o_rec in outer_recs}:&nbsp; &nbsp; &nbsp; &nbsp; print(f'{name} ({source})')&nbsp; &nbsp; &nbsp; &nbsp; print('=' * 15)&nbsp; &nbsp; &nbsp; &nbsp; for o_rec in outer_recs:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if o_rec.name == name:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f'* [{o_rec.thing}]: . "{o_rec.description}"')&nbsp; &nbsp; &nbsp; &nbsp; print()&nbsp; &nbsp; &nbsp; &nbsp; for sub_name, sub_source in {(i_rec.in_name, i_rec.in_source): None for i_rec in inner_recs}:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f'{sub_name} ({sub_source})')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('-' * 15)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i_rec in inner_recs:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if i_rec.in_name == sub_name:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f'* [{i_rec.thing}]: . "{i_rec.description}"')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print()print_outer_and_inner(o, i)主要缺点是它会在每个列表上循环多次,但它给你带来的是简洁性和可读性。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python