【问题标题】:Python, Avoid ugly nested for loopPython,避免丑陋的嵌套 for 循环
【发布时间】:2020-12-30 03:56:02
【问题描述】:

我是 python 编程的新手。 我已经尝试了很多来避免这些嵌套的 for 循环,但没有成功。

我的数据输入如下:

[
  {
    "province_id": "1",
    "name": "HCM",
    "districts": [
      {
        "district_id": "1",
        "name": "Thu Duc",
        "wards": [
          {
            "ward_id": "1",
            "name": "Linh Trung"
          },
          {
            "ward_id": "2",
            "name": "Linh Chieu"
          }
        ]
      },
      {
        "district_id": "2",
        "name": "Quan 9",
        "wards": [
          {
            "ward_id": "3",
            "name": "Hiep Phu"
          },
          {
            "ward_id": "4",
            "name": "Long Binh"
          }
        ]
      }
    ]
  },
  {
    "province_id": "2",
    "name": "Binh Duong",
    "districts": [
      {
        "district_id": "3",
        "name": "Di An",
        "wards": [
          {
            "ward_id": "5",
            "name": "Dong Hoa"
          },
          {
            "ward_id": "6",
            "name": "Di An"
          }
        ]
      },
      {
        "district_id": "4",
        "name": "Thu Dau Mot",
        "wards": [
          {
            "ward_id": "7",
            "name": "Hiep Thanh"
          },
          {
            "ward_id": "8",
            "name": "Hiep An"
          }
        ]
      }
    ]
  }
]

我的代码是:

for province in data:
    for district in province['districts']:
        for ward in district['wards']:
            # Excute my function
            print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))

输出

Linh Trung, Thu Duc, HCM
Linh Chieu, Thu Duc, HCM
Hiep Phu, Quan 9, HCM
...

即使我的代码可以运行,它看起来也很丑。
如何避免这些嵌套的 for 循环?

【问题讨论】:

  • 我不会担心嵌套循环......你有一个嵌套数据结构,所以嵌套循环是有意义的。
  • 这是处理数据的好方法。很容易看出发生了什么。无需更改任何内容。

标签: python nested-loops


【解决方案1】:

您的数据结构是自然嵌套的,但您可以选择编写一个生成器函数来对其进行迭代:

def all_wards(data):
    for province in data:
        for district in province['districts']:
            for ward in district['wards']:
                yield province, district, ward

此函数与您目前拥有相同的三重嵌套循环,但在您的代码中的其他任何地方,您现在都可以使用单个非嵌套循环遍历数据结构:

for province, district, ward in all_wards(data):
    print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))

如果您希望避免缩进过多,这是编写函数的等效方法,类似于@adarian 的答案,但不创建临时列表:

def all_wards(data):
    return (
        province, district, ward
        for province in data
        for district in province['districts']
        for ward in district['wards']
    )

【讨论】:

    【解决方案2】:

    这是一个单行版本

    [
        print("{}, {}, {}".format(ward["name"], district["name"], province["name"]))
        for province in data
        for district in province["districts"]
        for ward in district["wards"]
    ]
    
    

    【讨论】:

    • 这是一个有趣的解决方案,但创建一个列表只是为了它的副作用(在这种情况下,print)通常是不受欢迎的。在 python 中这是一件很诱人的事情,因为列表推导是一个很酷的工具。
    【解决方案3】:

    你可以这样做:

    def print_district(district, province):
        for ward in district['wards']:
            print('{}, {}, {}'.format(ward['name'], district['name'], province['name']))
    
    def print_province(province):
        for district in province['districts']:
            print_district(district, province)
    
    for province in data:   
        print_province(province)
    

    【讨论】:

      猜你喜欢
      • 2019-12-19
      • 2017-08-27
      • 2017-11-11
      • 1970-01-01
      • 2012-06-25
      • 2017-09-20
      • 2023-03-15
      • 1970-01-01
      • 2020-05-21
      相关资源
      最近更新 更多