【问题标题】:why does order of loop nesting matter python?为什么循环嵌套的顺序对python很重要?
【发布时间】:2016-04-21 05:35:36
【问题描述】:

我正在努力阅读这本书:用 python 自动化无聊的东西。 我在第 6 章的练习项目:台式打印机。 (https://automatetheboringstuff.com/chapter6/) - cmmd + F "表格打印机"

我设法找到了答案,但我发现我对嵌套循环的理解相当薄弱。为什么嵌套循环的顺序很重要?它如何影响它打印数据的方式?

这是数据:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
         ['Alice', 'Bob', 'Carol', 'David'],
         ['dogs', 'cats', 'moose', 'goose']]

这是第一个代码:

for a in range(len(tableData[0])):
    for b in range(len(tableData)):
        print(tableData[b][a],end = "")
    print()

然后打印出来:

  apples   Alice    dogs
 oranges     Bob    cats
cherries   Carol   moose
  banana   David   goose

这是第二个代码 (我切换了 a 和 b 的顺序嵌套,没有改变我想要打印的内容):

for b in range(len(tableData)):
    for a in range(len(tableData[0])):
        print(tableData[b][a],end = "")
    print()

它会打印这个:

apples orangescherries  banana
   Alice     Bob   Carol   David
    dogs    cats   moose   goose

这是第三个代码(我没有改变嵌套顺序,而是改变了我要打印的内容):

for a in range(len(tableData[0])):
    for b in range(len(tableData)):
        print(tableData[a][b],end = "")
    print()

它打印这个:

  apples orangescherries
   Alice     Bob   Carol
    dogs    cats   moose
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    printTable()
  File "<pyshell#11>", line 10, in printTable
    print(tableData[x][j].rjust(colWidths[0]),end = "")
IndexError: list index out of range

我难以理解的是:

(1) 第一个和第二个代码 - 为什么嵌套顺序会影响打印的内容?

(2) 第一个和第三个代码 - 为什么 print[a][b] 的顺序很重要?

很抱歉,这是一个非常长的问题,但我遇到了一些麻烦,请帮帮我。

【问题讨论】:

  • 为什么你认为顺序不重要? print "a" 后跟 print "b"print "b" 后跟 print "a" 不同。你真的了解for 循环的作用吗?
  • 是的,这就是我无法理解循环嵌套部分的原因。如果你能在网上给我一些解释,那就太好了!我知道解释它可能非常令人恼火。谢谢!
  • 如果你有一对嵌套循环,内循环体对每对外循环变量和内循环变量执行一次。顺序由循环结构决定。例如,(0,0), (0,1), (1,0), (1,1) 与 (0,0), (1,0), (0,1), (1,1 )。你只需要推理出来。这不是计算机语言问题,而是逻辑问题。这应该是你自己想一想就能弄清楚的事情。
  • 教程不是很好。如果您不明白某一点,请使用另一个教程。我推荐learnpythonthehardway.org

标签: python loops printing


【解决方案1】:

您在 Python 中创建表为 list,其中包含 lists。

table = [ ["row 0, column 0", "row 0, column 1", "row 0, column 2"],
          ["row 1, column 0", "row 1, column 1", "row 1, column 2"],
          ["row 2, column 0", "row 2, column 1", "row 2, column 2"],
          ["row 3, column 0", "row 3, column 1", "row 3, column 2"] ]

这就是您从这样的“多维”列表中访问项目的方式:

row = table[1]  # get row 1 (2nd item of the outer list)
item = row[3]  # from row 1, get column 3 (4th item of the inner list)

简而言之:

item = table[1][3]  # get item 1 of the outer list, and from that inner list get item 3

所以这就解释了为什么从“多维”列表访问项目时参数的顺序很重要,第一个索引选择行,第二个索引选择列(如果我们将列表的列表想象成上面描述的表格)。


现在是嵌套循环:

for row_number in range(len(table)):  # iterate over the row indices

    for column_number in range(len(table[row_number])):  # iterate over the column indices 
                                                         # of the current row

        print("Row:", row_number, "- Column:", column_number)
        print(" --> Item:", table[row_number][column_number])

        # <-- jump back to the column loop head here, if elements remaining

    # <-- jump back to the row loop head here, if elements remaining

因此,外循环(行)计数较慢,而内循环(列)计数较快,因为对于外循环的每一个迭代步骤,内循环对其所有元素执行一次完整的迭代。


但是,您不应该在 Python 中迭代列表索引,但您可以直接迭代列表项。这样也变得更清楚了:

for row in table:  # iterate over the rows (items of the outer list)

    for column in row:  # iterate over the columns of the current row (items of inner list)

        print("Row:", row_number, "- Column:", column_number)
        print(" --> Item:", table[row_number][column_number])

        # <-- jump back to the column loop head here, if elements remaining

    # <-- jump back to the row loop head here, if elements remaining

【讨论】:

  • 我同意你的最后一个建议,直接遍历列表项。但是,如果程序员想要以列优先顺序进行迭代,您应该扩展该示例以包括如何执行此操作,因为问题是关于行优先顺序和列优先顺序之间的区别。正确的方法是遍历转置的嵌套列表,如for column in zip(*table): for row in column:
  • 为了清楚起见,描述性变量名称的用法也很好,请接受我的投票 +1
  • 我会欣然接受,谢谢。也感谢列主排序。
【解决方案2】:

我做了一个 MSPaint 插图和类比,可能会对你有所帮助。

如果您将数据视为存在于矩形网格中,例如城市,那么它可能会有所帮助。想象一下,你有一个 4 个街区宽(从西到东)和 3 个街区长(从北到南)的城市。您想访问每个街区。

您访问时主要是从北到南旅行吗?您必须从第一个街区开始,然后向南走 3 个街区,然后向东移动一个街区,然后从北方重新开始。这样做 4 次。这称为“列主序”。

您在访问时主要是从西向东旅行吗?您必须从第一个街区开始,然后向东走 4 个街区,然后向南移动一个街区并从西边重新开始。这样做 3 次。这称为“行主要顺序”。

如您所见,您访问块的顺序不同,具体取决于您的访问路径是行优先还是列优先。按照箭头并将它们的顺序与数据输出的顺序相匹配。

在最后一种情况下,您仍按行主要顺序访问,但您只尝试向东 3 个街区和向南 4 个街区。您混淆了城市的尺寸,您可能最终会进入贫民区(在第三张图片中用一些问号表示)。

编辑:图片顺序错误。而我的话全都搞混了。我想它现在已经修复了。

【讨论】:

    猜你喜欢
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2013-05-18
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多