蚊章汇 - 循环
type: channel
link: https://linuxcn.bwsl.wang/tag/%E5%BE%AA%E7%8E%AF/
items: Lua 循环：如何使用 while 和 repeat until
items: Java 循环语句的简要指南
items: 如何在 Linux 的 bash 中永远循环
items: 如何在 Bash 中使用循环
items: 更深入的理解 Python 中的迭代

Lua 循环：如何使用 while 和 repeat until
type: item
date: 2023-02-25T23:28:04+08:00
description: 学习如何以及何时在 Lua 中使用 while 和 repeat until 循环。控制结构是编程语言的一个重要特征，因为它们使你能够根据通常在程序运行时动态建立的条件来指导程序的流程。不同的语言提供了不同的控制，在 Lua 中，有 while 循环、for 循环和 repeat until 循环。这篇文章涵盖了 while 和 repeat until 循环。由于它们的灵活性，我在一篇 单独的文章 中介绍 for 循环。条件是由一个使用运算符的表达式来定义的，运算符是你在数学课上可能认识的符号的一个花哨的术语。Lua 中有效的运算符有：== 等于~=不等于< 小于> 大于⇐小于或等于>= 大于或等于这些被称为关系运算符，因为它们比较两个值之间的关联。还有一些逻辑运算符，其含义与英语中的含义相同，可以纳入条件中，进一步描述你想检查的状态：andor下面是一些条件的例子：foo > 3：变量 foo 是否大于 3？foo 必须是 4 或更大才能满足这个条件。foo >= 3：foo 是否大于或等于 3？foo 必须是 3 或更大才能满足这个条件。foo > 3 and bar < 1：foo 是否大于 3 而 bar 小于 1？要满足这个条件，foo 变量必须在 bar 为 0 的同时为 4 或更大。foo> 3 or bar < 1：foo 是否大于 3？或者，bar 是否小于 1？如果 foo 是 4 或更大，或者 bar 是 0，那么这个条件就是真的。如果 foo 是 4 或更大，而 bar 是 0，会怎样？答案出现在本文的后面。While 循环只要满足某个条件，while 循环就会执行指令。例如，假设你正在开发一个应用来监测正在进行的僵尸末日。当没有剩余的僵尸时，就不再有僵尸末日了：zombie = 1024 while (zombie > 0) do print(zombie) zombie = zombie-1 end if zombie == 0 then print("No more zombie apocalypse!") end 运行代码，看僵尸消失：$ lua ./while.lua 1024 1023 [...] 3 2 1 No more zombie apocalypse! until 循环Lua 还有一个 repeat until 循环结构，本质上是一个带有 catch 语句的 while 循环。假设你在从事园艺工作，你想追踪还剩下什么可以收获的东西：mytable = { "tomato", "lettuce", "brains" } bc = 3 repeat print(mytable[bc]) bc = bc - 1 until( bc == 0 ) 运行代码：$ lua ./until.lua brains lettuce tomato 这很有帮助!无限循环一个无限循环有一个永远无法满足的条件，所以它无限地运行。这通常是一个由错误逻辑或你的程序中的意外状态引起的错误。例如，在本文的开头，我提出了一个逻辑难题。如果一个循环被设定为 foo > 3 or bar < 1 运行 ，那么当 foo 为 4 或更大而 bar 为 0 时，会发生什么？下面是解决这个问题的代码，为了以防万一，还使用了 break 语句安全捕获：foo = 9 bar = 0 while ( foo > 3 or bar < 1 ) do print(foo) foo = foo-1 -- safety catch if foo < -800000 then break end end 你可以安全地运行这段代码，但它确实模仿了一个意外的无限循环。有缺陷的逻辑是 or 运算符，它允许这个循环在 foo 大于 3 和 bar 小于 1 的情况下继续进行。and 运算符有不同的效果，但我让你去探索。无限循环实际上有其用途。图形应用使用技术上的无限循环来保持应用程序窗口的开放。我们没有办法知道用户打算使用这个程序多久，所以程序无限地运行，直到用户选择退出。在这些情况下使用的简单条件显然是一个总是被满足的条件。下面是一个无限循环的例子，为了方便起见，还是内置了一个安全陷阱：n = 0 while true do print(n) n = n+1 if n > 100 then break end end 条件 while true 总是被满足，因为 true 总是为真。这是比写 while 1 == 1 或类似的永远为真的简洁方式。Lua 中的循环从示例代码中可以看出，尽管有不同的实现方式，但循环基本上都是朝着同一个目标工作。选择一个对你来说有意义的，并且在你需要执行的处理过程中效果最好的。以防万一你需要它：终止失控循环的键盘快捷…

Java 循环语句的简要指南
type: item
date: 2023-01-31T17:30:59+08:00
description: 无论你使用的是 while 循环、do/while 循环，还是无限循环，了解循环的工作原理对 Java 编程至关重要。只要某些预定的条件为真，一个 while 循环就会执行一组任务。这被认为是一个控制结构，可以指导程序的流程。它是一种你可以通过定义一个条件来告诉你的代码要做什么的方法，它可以测试它，并根据它发现的情况采取行动。Java 中的两种 while 循环是 while 和 do/while。Java while 循环while 循环的目的是对数据进行迭代，直到某个条件得到满足。要创建一个 while 循环，你需要提供一个可以测试的条件，然后是你想要运行的代码。Java 有几个内置的测试函数，其中最简单的是数学运算符（<, >, ==, 等等）：package com.opensource.example; public class Example { public static void main(String[] args) { int count = 0; while (count < 5) { System.out.printf("%d ", count); count++; } } } 在这个简单的例子中，条件是变量 count 小于 5。因为 count 被实例化为 0，然后在 while 循环的代码中增加 1，所以程序总共迭代了 5 次：$ java ./while.java 0 1 2 3 4 在它进行第六次迭代之前，条件不再是真的，所以循环结束。while 循环的条件语句是至关重要的。弄错了可能意味着你的循环永远不会执行。例如，假设你把 count == 5 作为条件：while (count == 5) { System.out.printf("%d ", count); count++; 当你运行这段代码时，它的构建和运行都很成功，但什么也没有发生：$ java ./while.java $ 循环被跳过了，因为 count 被设置为 0，而且在第一次遇到 while 循环的时候，它还是 0。循环从未开始，count 也从未被递增。与此相反的是，当一个条件开始为真，并且永远不会为假时，这将导致一个无限循环。Java do while 循环与 while 循环相似，do/while 循环在每次迭代结束时测试条件，而不是在开始时测试条件。有了这个循环，循环中的代码至少运行一次，因为没有进入的入口，只有退出的出口:package com.opensource.example; public class Example { public static void main(String[] args) { int count = 9; do { System.out.printf("%d ", count); count++; } while(count == 5); } } 在这个示例代码中，count 被设置为 9。循环重复的条件是 count 等于 5，但是 9 不等于 5。不过，这个检查要到第一次迭代结束时才进行：$ java ./do.java 9 Java 无限循环无限循环，正如它的名字所示，永远不会结束。有时它们是被错误地创建的，但无限循环确实有一个有效的场景。有时你想让一个进程无限地继续下去（在功能上是无限的，因为你不能保证你需要它什么时候停止），因此你可能会把你的条件设置为不可能满足的东西。假设你写了一个应用程序，在僵尸天启期间计算留在你附近的僵尸的数量。为了模拟需要多少个循环才能达到 0 个僵尸的不确定性，我的演示代码从操作系统中检索了一个时间戳，并将计数器（c）的值设置为从该时间戳得出的某个数字。因为这是一个简单的例子，你不会真的想陷入一个无限循环，这段代码倒数到 0，并使用 break 函数来强制结束循环：package com.opensource.example; public class Example { public static void main(String[] args) { long myTime = System.currentTimeMillis(); int c; if ( myTime%2 == 0 ) { c = 128; } else { c = 1024; } while(true) { System.out.printf("%d Zombies\n", c); // break for convenience if ( c <= 0 ) { break; } c--; } } } 你可能要运行几次才能触发不同的僵尸总数，但有时你的程序会迭代 128 次，有时会迭代 1024 次：$ java ./zcount.java 1024 Zombies 102…

如何在 Linux 的 bash 中永远循环
type: item
date: 2020-07-01T18:38:27+08:00
description: 在 Linux 中有很多永远循环（或直到你决定停止）的方法，你可以在命令行或脚本中执行此操作。for 和 while 命令使这件事非常容易。关于相应的语法和策略，只有几件事要牢记。使用 while最简单的永远循环之一是使用 while 命令，后面跟上条件 true。 你不必使用诸如 while [ 1 -eq 1 ] 之类的逻辑或类似的测试。 while true 测试表示循环将一直运行，直到你使用 CTRL-C 停止循环、关闭终端窗口或注销为止。这是一个例子：$ while true > do > echo Keep running > sleep 3 > done Keep running Keep running Keep running ^C 你也可以使用 while : 做同样的事情。这里的关键是 : 总是返回成功，因此就像 while true 一样，此测试永远不会失败，并且循环会继续运行：$ while : > do > echo Keep running > sleep 3 > done Keep running Keep running ^C 如果你在脚本中插入了无限循环，并想提醒使用它的人如何退出脚本，那么可以使用 echo 命令添加提示：while : do echo Keep running echo "Press CTRL+C to exit" sleep 1 done 使用 forfor 命令还提供了一种永远循环的简便方法。虽然不如 while true 明显，但语法相当简单。你只需要在有界循环中替换参数即可，它通常类似于 “c 从等于 1 开始递增，直到 5”：$ for (( c=1; c<=5; c++ )) 不指定任何参数的情况下：$ for (( ; ; )) 没有起始值、增量或退出测试，此循环将永远运行或被强制停止：$ for (( ; ; )) > do > echo Keep running > echo “Press CTRL+C to exit” > sleep 2 > done Keep your spirits up Keep your spirits up Keep your spirits up 为什么要永远循环？在现实中，你不会想永远循环下去，但一直运行直到想要回家、工作完成或者遇到问题才退出并不罕见。任何构造为无限循环的循环都可以设置为根据各种情况退出。该脚本将一直处理数据直到下午 5 点，或者说检查发现第一次超过 5 点的时间：#!/bin/bash while true do if [ `date +%H` -ge 17 ]; then exit # exit script fi echo keep running ~/bin/process_data # do some work done 如果要退出循环而不是退出脚本，请使用 break 命令而不是 exit。#!/bin/bash while true do if [ `date +%H` -ge 17 ]; then break # exit loop fi echo keep running ~/bin/process_data done … run other commands here … 总结永远循环很容易。指定要停止循环的条件却需要花费一些额外的精力。via: https://www.networkworld.com/article/3562576/how-to-loop-forever-in-bash-on-linux.html作者：Sandra Henry-Stocker 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

如何在 Bash 中使用循环
type: item
date: 2020-04-09T06:57:54+08:00
description: 使用循环和查找命令批量自动对多个文件进行一系列的操作。人们希望学习批处理命令的一个普遍原因是要得到批处理强大的功能。如果你希望批量的对文件执行一些指令，构造一个可以重复运行在那些文件上的命令就是一种方法。在编程术语中，这被称作执行控制，for 循环就是其中最常见的一种。for 循环可以详细描述你希望计算机对你指定的每个数据对象（比如说文件）所进行的操作。一般的循环使用循环的一个简单例子是对一组文件进行分析。这个循环可能没什么用，但是这是一个安全的证明自己有能力独立处理文件夹里每一个文件的方法。首先，创建一个文件夹然后拷贝一些文件（例如 JPEG、PNG 等类似的文件）至文件夹中生成一个测试环境。你可以通过文件管理器或者终端来完成创建文件夹和拷贝文件的操作：$ mkdir example $ cp ~/Pictures/vacation/*.{png,jpg} example切换到你刚创建的那个新文件夹，然后列出文件并确认这个测试环境是你需要的：$ cd example $ ls -1 cat.jpg design_maori.png otago.jpg waterfall.png在循环中逐一遍历文件的语法是：首先声明一个变量（例如使用 f 代表文件），然后定义一个你希望用变量循环的数据集。在这种情况下，使用 * 通配符来遍历当前文件夹下的所有文件（通配符 * 匹配所有文件）。然后使用一个分号（;）来结束这个语句。$ for f in * ;取决于你个人的喜好，你可以选择在这里按下回车键。在语法完成前，shell 是不会尝试执行这个循环的。接下来，定义你想在每次循环中进行的操作。简单起见，使用 file 命令来得到 f 变量（使用 $ 告诉 shell 使用这个变量的值，无论这个变量现在存储着什么）所存储着的文件的各种信息：do file $f ;使用另一个分号结束这一行，然后关闭这个循环：done按下回车键启动 shell 对当前文件夹下所有东西的遍历。for 循环将会一个一个的将文件分配给变量 f 并且执行你的命令：$ for f in * ; do > file $f ; > done cat.jpg: JPEG image data, EXIF standard 2.2 design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced otago.jpg: JPEG image data, EXIF standard 2.2 waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced你也可以用这种形式书写命令：$ for f in *; do file $f; done cat.jpg: JPEG image data, EXIF standard 2.2 design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced otago.jpg: JPEG image data, EXIF standard 2.2 waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced对你的 shell 来说，多行和单行的格式没有什么区别，并且会输出完全一样的结果。一个实用的例子下面是一个循环在日常使用中的实用案例。假如你拥有一堆假期拍的照片想要发给你的朋友。但你的照片太大了，无法通过电子邮件发送，上传到图片分享服务也不方便。因此你想为你的照片创建小型的 web 版本，但是你不希望花费太多时间在一个一个的压缩图片体积上。首先，在你的 Linux、BSD 或者 Mac 上使用包管理器安装 ImageMagick 命令。例如，在 Fedora 和 RHEL 上：$ sudo dnf install ImageMagick在 Ubuntu 和 Debian 上：$ sudo apt install ImageMagick在 BSD 上，使用 ports 或者 pkgsrc 安装。在 Mac 上，使用 Homebrew 或者 MacPorts 安装。在你安装了 ImageMagick 之后，你就拥有一系列可以用来操作图片的新命令了。为你将要创建的文件建立一个目标文件夹：$ mkdir tmp使用下面的循环可以将每张图片减小至原来大小的 33%。$ for f in * ; do convert $f -scale 33% tmp/$f ; done然后就可以在 tmp 文件夹中看到已…

更深入的理解 Python 中的迭代
type: item
date: 2018-05-26T16:04:00+08:00
description: 深入探讨 Python 的 for 循环来看看它们在底层如何工作，以及为什么它们会按照它们的方式工作。Python 的 for 循环不会像其他语言中的 for 循环那样工作。在这篇文章中，我们将深入探讨 Python 的 for 循环来看看它们在底层如何工作，以及为什么它们会按照它们的方式工作。循环的问题我们将通过看一些“陷阱”开始我们的旅程，在我们了解循环如何在 Python 中工作之后，我们将再次看看这些问题并解释发生了什么。问题 1：循环两次假设我们有一个数字列表和一个生成器，生成器会返回这些数字的平方：>>> numbers = [1, 2, 3, 5, 7] >>> squares = (n**2 for n in numbers) 我们可以将生成器对象传递给 tuple 构造器，从而使其变为一个元组：>>> tuple(squares) (1, 4, 9, 25, 49) 如果我们使用相同的生成器对象并将其传给 sum 函数，我们可能会期望得到这些数的和，即 88。>>> sum(squares) 0 但是我们得到了 0。问题 2：包含的检查让我们使用相同的数字列表和相同的生成器对象：>>> numbers = [1, 2, 3, 5, 7] >>> squares = (n**2 for n in numbers) 如果我们询问 9 是否在 squares 生成器中，Python 将会告诉我们 9 在 squares 中。但是如果我们再次询问相同的问题，Python 会告诉我们 9 不在 squares 中。>>> 9 in squares True >>> 9 in squares False 我们询问相同的问题两次，Python 给了两个不同的答案。问题 3 ：拆包这个字典有两个键值对：>>> counts = {'apples': 2, 'oranges': 1} 让我们使用多个变量来对这个字典进行拆包：>>> x, y = counts 你可能会期望当我们对这个字典进行拆包时，我们会得到键值对或者得到一个错误。但是解包字典不会引发错误，也不会返回键值对。当你解包一个字典时，你会得到键：>>> x 'apples' 回顾：Python 的 for 循环在我们了解一些关于这些 Python 片段的逻辑之后，我们将回到这些问题。Python 没有传统的 for 循环。为了解释我的意思，让我们看一看另一种编程语言的 for 循环。这是一种传统 C 风格的 for 循环，用 JavaScript 编写：let numbers = [1, 2, 3, 5, 7]; for (let i = 0; i < numbers.length; i += 1) { print(numbers[i]) } JavaScript、 C、 C++、 Java、 PHP 和一大堆其他编程语言都有这种风格的 for 循环，但是 Python 确实没有。Python 确实没有 传统 C 风格的 for 循环。在 Python 中确实有一些我们称之为 for 循环的东西，但是它的工作方式类似于 foreach 循环。这是 Python 的 for 循环的风格：numbers = [1, 2, 3, 5, 7] for n in numbers: print(n) 与传统 C 风格的 for 循环不同，Python 的 for 循环没有索引变量，没有索引变量初始化，边界检查，或者索引递增。Python 的 for 循环完成了对我们的 numbers 列表进行遍历的所有工作。因此，当我们在 Python 中确实有 for 循环时，我们没有传统 C 风格的 for 循环。我们称之为 for 循环的东西的工作机制与之相比有很大的不同。定义：可迭代和序列既然我们已经解决了 Python 世界中无索引的 for 循环，那么让我们在此之外来看一些定义。可迭代是任何你可以用 Python 中的 for 循环遍历的东西。可迭代意味着可以遍历，任何可以遍历的东西都是可迭代的。for item in some_iterable: print(item) 序列是一种非常常见的可迭代类型，列表，元组和字符串都是序列。>>> numbers = [1, 2, 3, 5, 7] >>> coordinates = (4, 5, 7) >>> words = "hello there" 序列是可迭代的，它有一些特定的特征集。它们可以从 0 开始索引，以小于序列的长度结束，它们有一个长度并且它们可以被切分。列表，元组，字符串和其他所有序列都是这样工作的。>>> numbers[0] 1 >>> coordinates[2] 7 >>> words[4] 'o' Python…