本文根据官方文档 http://www.pythondoc.com/pythontutorial3/ 和 中文文档 http://www.pythondoc.com/pythontutorial3/ 翻译与整理, 代码测试运行环境为 win7, python3.6.

Python Tutorial
Release 3.6.8rc1
Python 教程
发行版本 3.6.8rc1

Guido van Rossum
and the Python development team
Guido van Rossum 和 Python 开发团队

December 17, 2018
2018/12/17

Python Software Foundation
Email: docs@python.org
Python软件基金会
电子邮箱: docs@python.org

CONTENTS
目录

文章目录

  • WHETTING YOUR APPETITE
  • 引起你的兴趣
  • USING THE PYTHON INTERPRETER
  • 使用 Python 解释器
    • 2.1 Invoking the Interpreter
    • 2.1 安装解释器
      • 2.1.1 Argument Passing
      • 2.1.1 参数传递
      • 2.1.2 Interactive Mode
      • 2.1.2 交互模式
    • 2.2 The Interpreter and Its Environment
    • 2.2 解释器及其环境
      • 2.2.1 Source Code Encoding
      • 2.2.1 源代码编码
  • AN INFORMAL INTRODUCTION TO PYTHON
  • 对 Python 的非正式介绍
    • 3.1 Using Python as a Calculator
    • 3.1 使用 Python 当做计算器
      • 3.1.1 Numbers
      • 3.1.1 数字
      • 3.1.2 Strings
      • 3.1.2 字符串
      • See also:
      • 参考:
      • 3.1.3 Lists
      • 3.1.3 列表
    • 3.2 First Steps Towards Programming
    • 3.2 迈向编程的第一步
  • MORE CONTROL FLOW TOOLS
  • 更深入控制流程工具
    • 4.1 if Statements
    • 4.1 if 语句
    • 4.2 for Statements
    • 4.2 for 语句
    • 4.3 The range() Function
    • range() 函数
    • 4.4 break and continue Statements, and else Clauses on Loops
    • 4.4 break 与 continue 语句, else 子句在循环中
    • 4.5 pass Statements
    • 4.5 pass 语句
    • 4.6 Defining Functions
    • 4.6 定义函数
    • 4.7 More on Defining Functions
    • 4.7 深入了解定义函数
      • 4.7.1 Default Argument Values
      • 4.7.1 默认参数值
      • 4.7.2 Keyword Arguments
      • 4.7.2 关键字参数
      • 4.7.3 Arbitrary Argument Lists
      • 4.7.3 随意参数列表
      • 4.7.4 Unpacking Argument Lists
      • 4.7.4 拆分参数列表
      • 4.7.5 Lambda Expressions
      • 4.7.5 λ 表达式
      • 4.7.6 Documentation Strings
      • 4.7.6 文档字符串
      • 4.7.7 Function Annotations
      • 4.7.7 函数注释
    • 4.8 Intermezzo: Coding Style
    • 4.8 间奏曲: 编码风格
  • DATA STRUCTURES
  • 数据结构
    • 5.1 More on Lists
    • 5.1 更多关于列表的内容
      • 5.1.1 Using Lists as ==Stacks==
      • 5.1.1 使用列表作为==堆栈==
      • 5.1.2 Using Lists as ==Queues==
      • 5.1.2 用列表作为==队列==
      • 5.1.3 List Comprehensions
      • 5.1.3 列表推导
      • 5.1.4 Nested List Comprehensions
      • 5.1.4 嵌套列表推导
    • 5.2 The del statement
    • 5.2 del 语句
    • 5.3 Tuples and Sequences
    • 5.3 元组和序列
    • 5.4 Sets
    • 5.4 集合
    • 5.5 Dictionaries
    • 5.5 字典
    • 5.6 Looping Techniques
    • 5.6 循环技巧
    • 5.7 More on Conditions
    • 5.7 更多关于条件(控制)
    • 5.8 Comparing Sequences and Other Types
    • 比较序列和其他类型

Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.
Python 是一门易学且强大的编程语言. 它高效的数据结构, 而且能简单但高效的方式去面向对象编程. Python 优雅的语法, 动态类型, 在加上它的解释性, 使其成为一个在脚本编程和 开发应用开发等多领域多 平台的理想语言.

The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python Web site, https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation.
Python 解释器和大多数标准库都是能以源码或适应所有主要平台的二进制文件免费获取在 Python 官网 https://www.python.org/, 而且可以是免费的分发. 这个站点同样包含发布的各种免费的第三方 Python 模块、程序、工具, 以及附加文档.

The Python interpreter is easily extended with new functions and data types implemented in C or C++ (or other languages callable from C). Python is also suitable as an extension language for customizable applications.
Python 解释器很容易扩展C or C++ (或其他C可调用的语言 )实现的新方法和数据类型. Python 也十分作为扩展语言为定制应用.

This tutorial introduces the reader informally to the basic concepts and features of the Python language and system. It helps to have a Python interpreter handy for hands-on experience, but all examples are self-contained, so the tutorial can be read off-line as well.
本教程指导读者了解 Python 语言及其体系的基本概念和特点. 亲身体验有助于方便的了解 Python 解释器, 而且所有的例子都是自足的, 所以这个教程可以被很好的离线阅读.

For a description of standard objects and modules, see library-index. reference-index gives a more formal definition of the language. To write extensions in C or C++, read extending-index and c-api-index. There are also several books covering Python in depth.
对于标准对象和模块的描述, 请查看库手册. 参考手册提供了更多语言的正式说明. 要写 C or C++ 扩展, 请阅读扩展索引和 c-api 索引. 当然还有有一些书籍去深入介绍 Python.

This tutorial does not attempt to be comprehensive and cover every single feature, or even every commonly used feature. Instead, it introduces many of Python’s most noteworthy features, and will give you a good idea of the language’s flavor and style. After reading it, you will be able to read and write Python modules and programs, and you will be ready to learn more about the various Python library modules described in library-index.
本教程不会尝试去全面且涵盖每个功能, 甚至是那些常用功能. 实际上, 它更多地介绍 Python 最有价值的功能 , 并且将给你一个好的理念在语言的 flavor 和风格上. 通过阅读本教程, 你将可以读写 Python 模块和程序, 而且你可以阅读学习更多各种关于 Python 库模块的描述在库手册中.

The Glossary is also worth going through.
词汇表 也是值得一试的.


CHAPTER
ONE
第一章


WHETTING YOUR APPETITE

引起你的兴趣

If you do much work on computers, eventually you find that there’s some task you’d like to automate. For example, you may wish to perform a search-and-replace over a large number of text files, or rename and rearrange a bunch of photo files in a complicated way. Perhaps you’d like to write a small custom database, or a specialized GUI application, or a simple game.

如果你有许多工作在电脑上处理, 终究你会发现这些任务使你像机器人. 比如, 你想处理大量文本文件的查找-替换操作, 或重命名并整理大量照片. 也许你想写一个小型自定义数据库, 一个特定 GUI 应用, 或是一个简单的小游戏

If you’re a professional software developer, you may have to work with several C/C++/Java libraries but find the usual write/compile/test/re-compile cycle is too slow. Perhaps you’re writing a test suite for such a library and find writing the testing code a tedious task. Or maybe you’ve written a program that could use an extension language, and you don’t want to design and implement a whole new language for your application.

如果你是一个专业软件开发者, 你可能必须使用多个 C/C++/Java 库, 但你会发现一般 编写/编译/测试/重新编译周期是非常慢的. 也许你正在写一个库的测试单元却发现在写测试代码是一个乏味的任务. 又或者你想写一个使用扩展语言的程序却不想设计和实现一个新的语言在你的应用中.

Python is just the language for you.
Python 正是你需要的语言

You could write a Unix shell script or Windows batch files for some of these tasks, but shell scripts are best at moving around files and changing text data, not well-suited for GUI applications or games. You could write a C/C++/Java program, but it can take a lot of development time to get even a first-draft program. Python is simpler to use, available on Windows, Mac OS X, and Unix perating systems, and will help you get the job done more quickly.
你可以写一个 Unix shell 脚本或 Windows 批处理文件来做一些任务, 但这些脚本最好是用来移动文件或是修改文本数据, 不是非常适合 在 GUI 程序或游戏. 你可以写一个 C/C++/Java 程序, 但它会花费程序员大量的时间在甚至是一个 first-draft 程序上. Python 是简单, 可用, 易获取的 在 Windows Mac OS X 和 Unix 操作系统上, 它将帮你更快地完成任务.

Python is simple to use, but it is a real programming language, offering much more structure and support for large programs than shell scripts or batch files can offer. On the other hand, Python also offers much more error checking than C, and, being a very-high-level language, it has high-level data types built in, such as flexible arrays and dictionaries. Because of its more general data types Python is applicable to a much larger problem domain than Awk or even Perl, yet many things are at least as easy in Python as in those languages.
Python 虽然简单易用, 但它也是一门真正的编程语言, 在大量程序上比shell脚本和批处理文件提供了很多更结构化和支持. 另一方面, Python 相较 C 提供了更多的错误检查, 是一门高级程序语言, 它有高级的数据类型, 像灵活数组字典等. 因为这些丰富的数据类型, Python 比 Awk 或甚于 Perl 语言更可应用于许多丰富编程领域, 也有很多事是非常容易的在 Python 语言上.

Python allows you to split your program into modules that can be reused in other Python programs. It comes with a large collection of standard modules that you can use as the basis of your programs — or as examples to start learning to program in Python. Some of these modules provide things like file I/O, system calls, sockets, and even interfaces to graphical user interface toolkits like Tk.

Python 允许你拆解你的程序到模块中, 这样它就可以被用在其他的 Python 程序里. Python 里有丰富的汇集的标准模块, 你可以把它们当做基本模块在你的程序中使用, 或是作为一个学习 Python 程序的案例. 一些模块提供像文件 I/O, 系统操作, 编程接口, 甚至可以与Tk等图形用户界面工具包接口.

Python is an interpreted language, which can save you considerable time during program development because no compilation and linking is necessary. The interpreter can be used interactively, which makes it easy to experiment with features of the language, to write throw-away programs, or to test functions during bottom-up program development. It is also a handy desk calculator.

Python 是一种解释性语言, 可以解约你大量的时间在程序开发中, 因为编译和链接不是必须的. 解释器可以用于交互式, 这使得它容易地展现语言特性, 或是写一次性程序, 或是在自上而下程序开发中测试函数. 它也可以是方便的桌面计算器.

Python enables programs to be written compactly and readably. Programs written in Python are typically much shorter than equivalent C, C++, or Java programs, for several reasons:

  • the high-level data types allow you to express complex operations in a single statement;
  • statement grouping is done by indentation instead of beginning and ending brackets;
  • no variable or argument declarations are necessary.

Python 使程序能够被简洁和便读地便写. Python 写程序一般是更短小比起同量的C, C++, 或 Java 程序. 因为以下几个原因:

  • 高级数据类型允许你表达复杂的操作在简单的语句中;
  • 语句块是通过缩进而不是开头和结尾括号来完成的;
  • 变量和参数声明不是必需的.

Python is extensible: if you know how to program in C it is easy to add a new built-in function or module to the interpreter, either to perform critical operations at maximum speed, or to link Python programs to libraries that may only be available in binary form (such as a vendor-specific graphics library). Once you are really hooked, you can link the Python interpreter into an application written in C and use it as an extension or command language for that application.

Python 是可扩展的: 如果你知道如何写 C 程序, 那么将很容易添加一个新的内置函数或者模块在解释器中, 或者以最大速度执行关键操作, 或链接到 Python 程序到库里, 这些库可能只二进制形式可用(比如供应商特定的图形库). 只要你真的 hooked , 你可以在 Python 解释器中加入 C 应用, 然后用它作为一个扩展或者是命令语言在这个应用中.

By the way, the language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged!

顺便说一句, 这种语言是以BBC节目"Monty Python的飞行马戏团"命名的, 与爬行动物无关. 提供参考到 Monty Python 技巧文档中不仅仅是允许的, 而且是被鼓励的!

Now that you are all excited about Python, you’ll want to examine it in some more detail. Since the best way to learn a language is to use it, the tutorial invites you to play with the Python interpreter as you read.

现在你肯定对 Python 感到很兴奋, 你将想更详细的研究它了. 自古以来, 学习一门语言的方法是经常用它, 这个教程推荐你在你阅读的时候使用 Python 解释器.

In the next chapter, the mechanics of using the interpreter are explained. This is rather mundane information, but essential for trying out the examples shown later.

在下一章, 将解释机器是如何运用这个解释器的. 这是相当平常的信息却非常重要的, 在尝试稍后显示的案例.

The rest of the tutorial introduces various features of the Python language and system through examples, beginning with simple expressions, statements and data types, through functions and modules, and finally touching upon advanced concepts like exceptions and user-defined classes.

教程的其他部分介绍 Python 语言的各种特性和操作案例, 开始时简单的表达式, 语句和数据类型, 接着是函数和模块, 最后接触先进概念上例外和用户自定义类.


CHAPTER
TWO
第二章


USING THE PYTHON INTERPRETER

使用 Python 解释器

2.1 Invoking the Interpreter

2.1 安装解释器

The Python interpreter is usually installed as /usr/local/bin/python3.6 on those machines where it is available; putting /usr/local/bin in your Unix shell’s search path makes it possible to start it by typing the command:

python3.6

to the shell[^1].Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local Python guru or system administrator. (E.g., /usr/local/python is a popular alternative location.)

Python 解释器通常被安装在机器的 /usr/local/bin/python3.6 目录下, 将 /usr/local/bin 放入你的 Unix shell 搜索路径, 以确保可以通过以下命令启动:

python3.6

由于解释器目录是可以选择的, 所以也有可能在其他目录; 检查你本地的 Python 或者询问管理员. (例如 /usr/local/python 也是非常热门的安装位置).

On Windows machines, the Python installation is usually placed in C:\Python36, though you can change this when you’re running the installer. To add this directory to your path, you can type the following command into the command prompt in a DOS box:

set path=%path%;C:\python36

在 Windows 机器中, Python 通常被安装在 C:\Python36, 也可以在你安装时改变位置. 你可以在 DOS box 键入以下命令将这个目录添加到环境变量 path 中.

Typing an end-of-file character (Control-D on Unix, Control-Z on Windows) at the primary prompt causes the interpreter to exit with a zero exit status. If that doesn’t work, you can exit the interpreter by typing the following command: quit().

键入文件截止符(Unix 上 ctrl+D, Win 上 ctrl+Z)是解释器中主要的以零状态退出方法. 如果这些不起作用, 你也可以键入命令 quit()来退出解释器.

The interpreter’s line-editing features include interactive editing, history substitution and code completion on systems that support readline. Perhaps the quickest check to see whether command line editing is supported is typing Control-P to the first Python prompt you get. If it beeps, you have command line editing; see Appendix Interactive Input Editing and History Substitution for an introduction to the keys. If nothing appears to happen, or if ^P is echoed, command line editing isn’t available; you’ll only be able to use backspace to remove characters from the current line.

解释器的行编辑特性包含交互式编辑, 历史替换, 和系统上的代码完成, 它支持 readline. 也许快速检查去查看是否命令行编辑被支持是通过键入 ctrl+p 在你获得第一个 Python 提示. 如果它发出哔哔声, 你可以进行行命令编辑; 相关介绍请查看 附录 里交互式输入编辑和历史记录. 如果啥事都没有发生, 或显示 ^p, 那么命令行编辑是不可用的; 你只有用退格键从当前行移除字符.

The interpreter operates somewhat like the Unix shell: when called with standard input connected to a tty device, it reads and executes commands interactively; when called with a file name argument or with a file as standard input, it reads and executes a script from that file.

解释器的操作有些像 Unix shell: 当标准输入连接到tty设备时调用, 它将读取并立即执行命令; 当使用文件名参数或文件作为标准输入调用时, 它将把文件当做一个脚本读取并执行.

A second way of starting the interpreter is python -c command [arg] …, which executes the statement(s) in command, analogous to the shell’s -c option. Since Python statements often contain spaces or other characters that are special to the shell, it is usually advised to quote command in its entirety with single quotes.

第二种方式开始解释器是 Python -c command [arg] ..., 它在命令中执行语句, 类似 shell 的 -c 选项. 由于 Python 语句经常包含空格或者其他shell 特殊字符, 通常建议用单引号引用命令为一个整体.

Some Python modules are also useful as scripts. These can be invoked using python -m module [arg] …, which executes the source file for module as if you had spelled out its full name on the command line.

Python 的一些模块也经常被当做脚本使用. 这些可以使用 python -m module [arg] … 来调用, 执行源文件的模块就像你已经拼写出来它的全名(完整路径名, 译注)在命令行中.

When a script file is used, it is sometimes useful to be able to run the script and enter interactive mode afterwards. This can be done by passing -i before the script. All command line options are described in using-on-general.

当一个脚本文件被使用时, 它有时经常能运行的脚本, 然后进入交互模式. 这个可以在脚本前加入 -i 来实现. 所有命令行选项在 using-on-general 被描述.

2.1.1 Argument Passing

2.1.1 参数传递

When known to the interpreter, the script name and additional arguments thereafter are turned into a list of strings and assigned to the argv variable in the sys module. You can access this list by executing import sys. The length of the list is at least one; when no script and no arguments are given, sys.argv[0] is an empty string. When the script name is given as ‘-’ (meaning standard input), sys.argv[0] is set to ‘-’.
When -c command is used, sys.argv[0] is set to ‘-c’. When -m module is used, sys.argv[0] is set to the full name of the located module. Options found after -c command or -m module are not consumed by the Python interpreter’s option processing but left in sys.argv for the command or module to handle.
当调用解释器时, 脚本的名和添加的参数后被转变为一个字符串列表, 而且被赋值到 argv 这个变量在 sys 模块中. 你可以通过引入 sys 模块使用这个列表. 列表的长度至少为一; 当没有给予脚本和参数时, sys.argv[0] 是一个空字符串. 当给予的脚本名是 ‘-’(意为标准输入), sys.argv[0] 被设置为 ‘-’.
当 -c command 被使用时, sys.argv[0] 被设置为 ‘-c’. 当 -m module 被使用时, sys.argv[0] 被设置为本地模块的全名. 找到选项之前 -c command 或 -m module 不会被Python 解释器的选项处理机制截获. 而是留下了在sys.argv中给命令或模块要去处理.

2.1.2 Interactive Mode

2.1.2 交互模式

When commands are read from a tty, the interpreter is said to be in interactive mode. In this mode it prompts for the next command with the primary prompt, usually three greater-than signs (>>>); for continuation lines it prompts with the secondary prompt, by default three dots (…). The interpreter prints a welcome message stating its version number and a copyright notice before printing the first prompt:

$ python3.6
Python 3.6 (default, Sep 16 2015, 09:25:04)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

当从 tty 中 读取命令, 解释器被称作是交互模式. 在这种模式中, 它会提供下一个命令的主要提示, 通常是三个大于符(>>>); 对于延续 行, 它提供了第二种提示, 默认是三个点号(…). 解释器会在开始显示欢迎信息和版本号和一个版权注意, 在显示第一个提示符前:

PS C:\Users\huwho> python
Python 3.6.6rc1 (v3.6.6rc1:1015e38be4, Jun 12 2018, 08:38:06) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

Continuation lines are needed when entering a multi-line construct. As an example, take a look at this if statement:

>>> the_world_is_flat = True
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
...
Be careful not to fall off!

For more on interactive mode, see Interactive Mode.

当进入一个多行结构时需要延续线. 举个例子, 看下这个 if 语句:

>>> the_world_is_flat = True
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
...
Be careful not to fall off!

关于交互模式更多的, 请看 交互模式.

2.2 The Interpreter and Its Environment

2.2 解释器及其环境

2.2.1 Source Code Encoding

2.2.1 源代码编码

By default, Python source files are treated as encoded in UTF-8. In that encoding, characters of most languages in the world can be used simultaneously in string literals, identifiers and comments — although the standard library only uses ASCII characters for identifiers, a convention that any portable code should follow. To display all these characters properly, your editor must recognize that the file is UTF-8, and it must use a font that supports all the characters in the file.
默认地, Python 源文件的编码格式是 UTF-8. 在这种编码方式中, 世界上大多数语言的字符可以同时使用在字符串文字, 标识符和注释中, 虽然标准库仅仅使用 ASCCⅡ 字符作为标识符, 按惯例这是任何可移植语言需要遵守的. 要正确地显示这些字符, 你的编辑器最认识的这个文件是 UTF-8, 而且最好使用一种支持所有字符的字体在文件中.

To declare an encoding other than the default one, a special comment line should be added as the first line of the file. The syntax is as follows:

# -*- coding: encoding -*-

where encoding is one of the valid codecs supported by Python.
要声明一种不同于默认的编码, 一个特别的说明行需要被添加在文件的第一行. 语法如下:

# -*- coding: encoding -*-

这里的 encoding 是 Python 支持的有效编码中的一种.

For example, to declare that Windows-1252 encoding is to be used, the first line of your source code file
should be:

# -*- coding: cp1252 -*-

比如, 声明使用 Windows-1252, 你的源码文件第一行应该是:

# -*- coding: cp1252 -*-

One exception to the first line rule is when the source code starts with a UNIX “shebang” line. In this case,
the encoding declaration should be added as the second line of the file. For example:

#!/usr/bin/env python3
# -*- coding: cp1252 -*-

一个例外规则是当源码的开始是 UNIX “shebang” 行. 这种情况下, 编码方式声明应该被添加在第二行. 例如:

#!/usr/bin/env python3
# -*- coding: cp1252 -*-

CHAPTER
THREE
第三章


AN INFORMAL INTRODUCTION TO PYTHON

对 Python 的非正式介绍

In the following examples, input and output are distinguished by the presence or absence of of prompts (>>> and …): to repeat the example, you must type everything after the prompt, when the prompt appears; lines that do not begin with a prompt are output from the interpreter. Note that a secondary prompt on a line by itself in an example means you must type a blank line; this is used to end a multi-line command.
在接下来的例子中, 输入输出都是通过提示符(>>> 和 …)的是否存在区别: 为了重现案例, 你键入所以内容必须在提示符后, 即当提示符显现; 解释器输出行不以提示符开头. 注意, 案例中一行自己出现第二种提示符表示你必须键入一个空行; 它被用在在多行命令的最后.

Many of the examples in this manual, even those entered at the interactive prompt, include comments. Comments in Python start with the hash character, #, and extend to the end of the physical line. A comment may appear at the start of a line or following whitespace or code, but not within a string literal. A hash character within a string literal is just a hash character. Since comments are to clarify code and are not interpreted by Python, they may be omitted when typing in examples.
Some examples:

# this is the first comment
spam = 1 # and this is the second comment
# ... and now a third!
text = "# This is not a comment because it's inside quotes."

手册中许多案例, 甚至输入在交互式提示符的, 都包含注释. 在 Python 中注释以哈希字符 # 开头, 到实际的行尾结束. 注释一般显示在开始的一行, 接着留白或者是代码, 但不要混在一个字符串里. 文本字符串中哈希字符(#)就是普通的哈希字符. 注释一直以来是阐明代码的, 它们不用被解释在 Python 中, 它们可以被忽略当键入例子时.
一些例子:

# this is the first comment
spam = 1 # and this is the second comment
# ... and now a third!
text = "# This is not a comment because it's inside quotes."

3.1 Using Python as a Calculator

3.1 使用 Python 当做计算器

Let’s try some simple Python commands. Start the interpreter and wait for the primary prompt, >>>. (It
shouldn’t take long.)
现在让我们尝试些简单的 Python 命令. 启动解释器, 等待主提示符>>> 出现. (一般不会太久)

3.1.1 Numbers

3.1.1 数字

The interpreter acts as a simple calculator: you can type an expression at it and it will write the value. Expression syntax is straightforward: the operators +, -, * and / work just like in most other languages (for example, Pascal or C); parentheses (()) can be used for grouping. For example:

>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating point number
1.6

解释器作为简单的计算器: 你可以键入一个表达式, 然后它将写出值. 表达式语法是很直接: 操作符 +,-,*,/ 作用和其他大多数语言(比如, Pascal 或者 C)一样; 括弧(())被用于分组. 比如:

>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating point number
1.6

The integer numbers (e.g. 2, 4, 20) have type int, the ones with a fractional part (e.g. 5.0, 1.6) have type float. We will see more about numeric types later in the tutorial.
整数(e.g. 2, 4, 20)是整数类型, 有小数部分的数字(e.g. 5.0, 1.6)是浮点数类型. 我们将在接下来的教程中看到更多数据类型.

Division (/) always returns a float. To do floor division and get an integer result (discarding any fractional result) you can use the // operator; to calculate the remainder you can use %:

>>> 17 / 3 # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3 # floor division discards the fractional part
5
>>> 17 % 3 # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2 # result * divisor + remainder
17

除法(/) 永远返回一个浮点数. 为了使用 floor 除法得到一个整数结果(舍去所有小数部分), 你可以使用 // 操作符; 为了计算余数你可以使用 %:

>>> 17 / 3 # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3 # floor division discards the fractional part
5
>>> 17 % 3 # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2 # result * divisor + remainder
17

With Python, it is possible to use the ** operator to calculate powers1:

>>> 5 ** 2 # 5 squared
25
>>> 2 ** 7 # 2 to the power of 7
128

在 Python, 可以使用 **操作符进行幂的乘方计算:

>>> 5 ** 2 # 5 squared
25
>>> 2 ** 7 # 2 to the power of 7
128

The equal sign (=) is used to assign a value to a variable. Afterwards, no result is displayed before the next interactive prompt:

>>> width = 20
>>> height = 5 * 9
>>> width * height
900

等号(=)用于给变量赋值. 然后, 结果不会在下一个提示符前显示:

>>> width = 20
>>> height = 5 * 9
>>> width * height
900

If a variable is not “defined” (assigned a value), trying to use it will give you an error:

>>> n # try to access an undefined variable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

如果变量没有被"定义"(赋值), 在尝试使用它时会得到一个错误:

>>> n # try to access an undefined variable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

There is full support for floating point; operators with mixed type operands convert the integer operand to floating point:

>>> 4 * 3.75 - 1
14.0

对浮点数是有全程支持; 操作混合类型操作数转换整数操作数为浮点数:

>>> 4 * 3.75 - 1
14.0

In interactive mode, the last printed expression is assigned to the variable _. This means that when you are using Python as a desk calculator, it is somewhat easier to continue calculations, for example:

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

This variable should be treated as read-only by the user. Don’t explicitly assign a value to it — you would create an independent local variable with the same name masking the built-in variable with its magic behavior.
在交互模式中, 最后打印的表达式被赋值给变量 _. 也就是说当你将 Python 作为桌面计算器使用时, 它比较容易地继续计算, 比如:

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

这个变量应该被用户当做只读对待. 不要明确地赋值给它, 这样你将建立一个单独本地变量, 而这个同名将掩蔽内置变量的魔术行为.

In addition to int and float, Python supports other types of numbers, such as Decimal and Fraction. Python also has built-in support for complex numbers, and uses the j or J suffix to indicate the imaginary part (e.g. 3+5j).
除了 int 和 float, Python 还支持其他的数字类型, 像 Decimal(精确小数类型) 和 Fraction(有理数). Python 对complex numbers(复数)有同样内置的支持, 使用 j 或者 J 后缀来表示虚数部分(e.g. 3+5j).

3.1.2 Strings

3.1.2 字符串

Besides numbers, Python can also manipulate strings, which can be expressed in several ways. They can be enclosed in single quotes (’…’) or double quotes ("…") with the same result2. \ can be used to escape quotes:

>>> 'spam eggs' # single quotes
'spam eggs'
>>> 'doesn\'t' # use \' to escape the single quote...
"doesn't"
>>> "doesn't" # ...or use double quotes instead
"doesn't"
>>> '"Yes," they said.'
'"Yes," they said.'
>>> "\"Yes,\" they said."
'"Yes," they said.'
>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'

除了数字, Python 也支持操纵字符串, 它可以使用几种不同的表达方式. 它们可以是封闭在单引号(’…’)或是双引号(’…’)中, 结果是一样的. \可以用来转义引号:

>>> 'spam eggs' # single quotes
'spam eggs'
>>> 'doesn\'t' # use \' to escape the single quote...  #`\`转义单引号
"doesn't"
>>> "doesn't" # ...or use double quotes instead  # 双引号 单引号下不用转义
"doesn't"
>>> '"Yes," they said.'     # 单引号中双引号也不用转义
'"Yes," they said.'
>>> "\"Yes,\" they said."
'"Yes," they said.'
>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'

In the interactive interpreter, the output string is enclosed in quotes and special characters are escaped with backslashes. While this might sometimes look different from the input (the enclosing quotes could change) the two strings are equivalent. The string is enclosed in double quotes if the string contains a single quot and no double quotes, otherwise it is enclosed in single quotes. The print() function produces a more readable output, by omitting the enclosing quotes and by printing escaped and special characters:

>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'
>>> print('"Isn\'t," they said.')
"Isn't," they said.
>>> s = 'First line.\nSecond line.' # \n means newline
>>> s # without print(), \n is included in the output
'First line.\nSecond line.'
>>> print(s) # with print(), \n produces a new line
First line.
Second line.

在解释器中, 输出字符串是被封闭在引号里, 而特殊字符里被反斜线转义. 虽然有时候看有些不同输入(封闭的引号可能改变)的两个字符串是等值的. 封闭在双引号的字符串如果字符串里包含单引号没有双引号, 否则就封闭在单引号. print() 函数提供一个高可读输出, 通过省去引号且打印被转义的特殊字符:

>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'
>>> print('"Isn\'t," they said.')
"Isn't," they said.
>>> s = 'First line.\nSecond line.' # \n means newline
>>> s # without print(), \n is included in the output
'First line.\nSecond line.'
>>> print(s) # with print(), \n produces a new line
First line.
Second line.

If you don’t want characters prefaced by \ to be interpreted as special characters, you can use raw strings by adding an r before the first quote:

>>> print('C:\some\name') # here \n means newline!
C:\some
ame
>>> print(r'C:\some\name') # note the r before the quote
C:\some\name

如果你不想字符前面的 \ 被解释为特殊字符, 你可以通过在第一个引号前添加 r 来使用原生字符串.

String literals can span multiple lines. One way is using triple-quotes: “”"…""" or ‘’’…’’’. End of lines are automatically included in the string, but it’s possible to prevent this by adding a \ at the end of the line. The following example:

print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")

produces the following output (note that the initial newline is not included):

Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to

字符串文本可以跨越多行. 一种方式是使用三引号: “”"…""" 或 ‘’’…’’’. 行尾自动地包含在字符串中, 但可以通过在行尾添加一个 \ 来阻止这个行为. 下例:

print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")

产生如下输出(注意这开始的新行没有被包含):

Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to

Strings can be concatenated (glued together) with the + operator, and repeated with *:

>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'

字符串可以通过操作符 + 被连接(粘在一起), 通过 * 重复:

>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'

Two or more string literals (i.e. the ones enclosed between quotes) next to each other are automatically concatenated.

>>> 'Py' 'thon'
'Python'

两个或更多字符文本(即: 引号之间包含的那些)彼此相邻是自动地连接的.

>>> 'Py' 'thon'
'Python'

This feature is particularly useful when you want to break long strings:

>>> text = ('Put several strings within parentheses '
... 'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'

这个特性是尤其有用的, 当你想打开长字符串:

>>> text = ('Put several strings within parentheses '
... 'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'

This only works with two literals though, not with variables or expressions:

>>> prefix = 'Py'
>>> prefix 'thon' # can't concatenate a variable and a string literal
...
SyntaxError: invalid syntax
>>> ('un' * 3) 'ium'
...
SyntaxError: invalid syntax

它只用在两个文本上, 不能是变量或表达式:

>>> prefix = 'Py'
>>> prefix 'thon' # can't concatenate a variable and a string literal
...
SyntaxError: invalid syntax
>>> ('un' * 3) 'ium'
...
SyntaxError: invalid syntax

If you want to concatenate variables or a variable and a literal, use +:

>>> prefix + 'thon'
'Python'

如果你想连接变量和文本, 请使用 +:

>>> prefix + 'thon'
'Python'

Strings can be indexed (subscripted), with the first character having index 0. There is no separate character type; a character is simply a string of size one:

>>> word = 'Python'
>>> word[0] # character in position 0
'P'
>>> word[5] # character in position 5
'n

字符串可以被索引(下标), 而第一个字符就是索引 0. 这里没有单独的字符类型; 字符只是大小为一的字符串:

>>> word = 'Python'
>>> word[0] # character in position 0
'P'
>>> word[5] # character in position 5
'n

Indices may also be negative numbers, to start counting from the right:

>>> word[-1] # last character
'n'
>>> word[-2] # second-last character
'o'
>>> word[-6]
'P

Note that since -0 is the same as 0, negative indices start from -1.
索引也有可能是负数, 从右边开始去计数:

>>> word[-1] # last character
'n'
>>> word[-2] # second-last character
'o'
>>> word[-6]
'P

注意, 由于 -0 和 0 是一样的, 所以负数索引是从 -1 开始的.

In addition to indexing, slicing is also supported. While indexing is used to obtain individual characters, slicing allows you to obtain substring:

>>> word[0:2] # characters from position 0 (included) to 2 (excluded)
'Py'
>>> word[2:5] # characters from position 2 (included) to 5 (excluded)
'tho'

Note how the start is always included, and the end always excluded. This makes sure that s[:i] + s[i:] is always equal to s:

>>> word[:2] + word[2:]
'Python'
>>> word[:4] + word[4:]
'Python

除了索引, 切片 也是被支持的. 只不过索引用来获取单个字符, 切片使你获得字符串:

>>> word[0:2] # characters from position 0 (included) to 2 (excluded)  #从 0 到 2, 包含位置 0, 但不包含位置2
'Py'
>>> word[2:5] # characters from position 2 (included) to 5 (excluded)
'tho'

注意, 不管怎么样, 开始位置总是包含的, 结束位置总是排除的. 这保证了 s[:i] + s[i:] 总是等于 s:

>>> word[:2] + word[2:]
'Python'
>>> word[:4] + word[4:]
'Python

Slice indices have useful defaults; an omitted first index defaults to zero, an omitted second index defaults
to the size of the string being sliced.

>>> word[:2] # character from the beginning to position 2 (excluded)
'Py'
>>> word[4:] # characters from position 4 (included) to the end
'on'
>>> word[-2:] # characters from the second-last (included) to the end
'on'

切片的索引有一般的默认值; 忽略的第一个索引是零, 忽略的第二个索引是字符串被切片长度.

>>> word[:2] # character from the beginning to position 2 (excluded)
'Py'
>>> word[4:] # characters from position 4 (included) to the end
'on'
>>> word[-2:] # characters from the second-last (included) to the end
'on'

One way to remember how slices work is to think of the indices as pointing between characters, with the left edge of the first character numbered 0. Then the right edge of the last character of a string of n characters has index n, for example:

+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0   1   2   3   4   5   6
-6 -5  -4  -3  -2  -1

The first row of numbers gives the position of the indices 0…6 in the string; the second row gives the corresponding negative indices. The slice from i to j consists of all characters between the edges labeled i and j, respectively.
For non-negative indices, the length of a slice is the difference of the indices, if both are within bounds. For example, the length of word[1:3] is 2.
一种方法去记住切片如工作是去想下把索引作为字符之间的点, 第一个字符的左边是数字 0. 接着有 n 个字符的字符串的最后一个字符的右边是索引 n, 如下:

+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0   1   2   3   4   5   6
-6 -5  -4  -3  -2  -1

第一行的数字给出了在字符串中索引 0…6 的位置; 第二行给出相应的负数索引. 从i到j的切片分别由标记为i和j的边之间的所有字符组成.
对于非负索引的, 切片长度是索引的差, 如果它们都在界限内. 例如, word[1:3]的长度是 2.

Attempting to use an index that is too large will result in an error:

>>> word[42] # the word only has 6 characters
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range

However, out of range slice indexes are handled gracefully when used for slicing:

>>> word[4:42]
'on'
>>> word[42:]
''

当尝试使用一个太大的索引时, 结果会出现报错:

>>> word[42] # the word only has 6 characters
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range

然而, 使用不在切片范围的索引去切片时会优雅的处理:

>>> word[4:42]
'on'
>>> word[42:]
''

Python strings cannot be changed — they are immutable. Therefore, assigning to an indexed position in the string results in an error:

>>> word[0] = 'J'
...
TypeError: 'str' object does not support item assignment
>>> word[2:] = 'py'
...
TypeError: 'str' object does not support item assignment

If you need a different string, you should create a new one:

>>> 'J' + word[1:]
'Jython'
>>> word[:2] + 'py'
'Pypy'

Python 字符串不能被改变————它们是不可变的. 正因为如此, 赋值在字符串的一个索引位置的结果是一个报错:

>>> word[0] = 'J'
...
TypeError: 'str' object does not support item assignment
>>> word[2:] = 'py'
...

如果你需要一个不同的字符串, 你应该创建一个新的:

>>> 'J' + word[1:]
'Jython'
>>> word[:2] + 'py'
'Pypy'

The built-in function len() returns the length of a string:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

内置函数 len() 返回一个字符串的长度:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34

See also:

  • textseq Strings are examples of sequence types, and support the common operations supported by such types.
  • string-methods Strings support a large number of methods for basic transformations and searching.
  • f-strings String literals that have embedded expressions.
  • formatstrings Information about string formatting with str.format.
  • old-string-formatting The old formatting operations invoked when strings are the left operand of the % operator are described in more detail here.

参考:

  • textseq 字符串是序列类型的示例, 它支持那些类型所支持的共同操作.
  • string-methods 字符串支持大量基本的转换和搜索方法.
  • f-strings 字符串文本能嵌入表达式.
  • formatstrings 描述字符串格式化的信息在这 str.format().
  • old-string-formatting 这里描述了旧式的字符串格式化操作, 它们在字符串和Unicode字符串是 % 操作符的左操作数时调用.

3.1.3 Lists

3.1.3 列表

Python knows a number of compound data types, used to group together other values. The most versatile is the list, which can be written as a list of comma-separated values (items) between square brackets. Lists might contain items of different types, but usually the items all have the same type.

>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]

Python 支持数种符合数据类型, 用于将其他值组合在一起. 最多通用的是列表, 它可以写入一列用逗号隔开的值(项目)在方括号里. 列表可以包含不同类型的项目, 但通常项目都是同样的数据类型.

>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
>>> squares1 = [1, 4, 9, 16, 'iyuy']
>>> squares1
[1, 4, 9, 16, 'iyuy']

Like strings (and all other built-in sequence type), lists can be indexed and sliced:

>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]

如同字符串(当然也包括其他的内置序列类型), 列表也可以使用索引和切片:

>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]

All slice operations return a new list containing the requested elements. This means that the following slice returns a new (shallow) copy of the list:

>>> squares[:]
[1, 4, 9, 16, 25]

所有的切片操作都返回一个新的列表, 它里面包含所请求的元素. 这也就是说下面的切片返回的是一个复制来的新(shallow)列表:

>>> squares[:]
[1, 4, 9, 16, 25]

Lists also support operations like concatenation:

>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Unlike strings, which are immutable, lists are a mutable type, i.e. it is possible to change their content:
>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]

同样列表也支持连接操作:

>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Unlike strings, which are immutable, lists are a mutable type, i.e. it is possible to change their content:

>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]

不同于字符串的不可改变, 列表是变动类型, 即它可以改变它里面的内容:

>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]
>>> cubes[3:5]=[60, 120] # 也可以切片改变更多
>>> cubes
[1, 8, 27, 60, 120]
>>>

You can also add new items at the end of the list, by using the append() method (we will see more about methods later):

>>> cubes.append(216) # add the cube of 6
>>> cubes.append(7 ** 3) # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]

你也可以在列表后面添加一个新的项目, 通过 append() 方法(我们将在后面看到更多相关方法):

>>> cubes.append(216) # add the cube of 6
>>> cubes.append(7 ** 3) # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]

Assignment to slices is also possible, and this can even change the size of the list or clear it entirely:

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]

用切边赋值也是可以的, 甚至这可以改变列表的大小, 或完全清空它:

>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]

The built-in function len() also applies to lists:

>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4

内置函数 len() 也可以用在裂变上:

>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4

It is possible to nest lists (create lists containing other lists), for example:

>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b

允许 nest 列表(创建列表包含其他列表), 例如:

>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b

3.2 First Steps Towards Programming

3.2 迈向编程的第一步

Of course, we can use Python for more complicated tasks than adding two and two together. For instance, we can write an initial sub-sequence of the Fibonacci series as follows:

>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
...     print(b)
...     a, b = b, a+b
...
1
1
2
3
5
8

This example introduces several new features.

  • The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.
  • The while loop executes as long as the condition (here: b < 10) remains true. In Python, like in C, any non-zero integer value is true; zero is false. The condition may also be a string or list value, in fact any sequence; anything with a non-zero length is true, empty sequences are false. The test used in the example is a simple comparison. The standard comparison operators are written the same as in C: < (less than), > (greater than), == (equal to), <= (less than or equal to), >= (greater than or equal to) and != (not equal to).
  • The body of the loop is indented: indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount.
  • The print() function writes the value of the argument(s) it is given. It differs from just writing the expression you want to write (as we did earlier in the calculator examples) in the way it handles multiple arguments, floating point quantities, and strings. Strings are printed without quotes, and a space is inserted between items, so you can format things nicely, like this:
    >>> i = 256*256
    >>> print('The value of i is', i)
    The value of i is 65536
    

    The keyword argument end can be used to avoid the newline after the output, or end the output with a different string:

    >>> a, b = 0, 1
    >>> while b < 1000:
    ...     print(b, end=',')
    ...     a, b = b, a+b
    ...
    1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    

当然, 我们可以用 Python 处理比二加二更复杂任务. 例如, 我们可以写一个初始的菲波那契( Fibonacci series)子序列, 如下:

>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
...     print(b)
...     a, b = b, a+b
...
1
1
2
3
5
8

这个例子介绍了数个新特性.

  • 第一行包含一个多赋值语句: 变量 a 和 b 同时获得新值 0 和 1. 在最后一行它被再次使用, 表明在任何赋值发生前, 右侧表达式是首先计算的. 右边表达式是从左到右计算的.
  • while 循环当条件(此处: b < 10)为真时会一直执行. 在 Python中, 和 C 一样, 所有非零整数值都为真; 零是假. 条件也可以是字符串或者列表值, 实际上是任何序列值; 任何非零长是 true, 空序列为 false. 在案例中,测试使用的是简单比较. 标准的比较运算符写作和 C 一样: < (小于), > (大于), == (等于), <= (小于等于), >= (大于等于) 和 != (不等于).
  • 循环体是缩进的: 缩进是 Python 组织语句的方式. 在交互式提示, 你必须键入 制表符 或者空格在每一个缩进的行. 在实践中, 你将准备更复杂的 Python 输入在文本编辑器里; 所有像样的文本编辑器有自动缩进功能. 当复杂语句是以交互方式进入, 它必须跟一个空白行去表明复杂状况(由于解析器不会猜测在你已经键入最后一行时). 注意, 每一个基础块必须是同样缩进.
  • 函数 print() 输出给定参数的值. 它不仅仅是写出你想写的表达式(就像我们之前的计算器例子)通过操作多个参数,浮点数量和字符串. 字符串打印没有引号, 而且项目之间会被插入一个空格, 所以你想更漂亮滴格式化东西, 要想这样:
    >>> i = 256*256
    >>> print('The value of i is', i)
    The value of i is 65536
    

    关键字参数 end 可用于在输出后避免换行, 或者使用不同的字符串结束输出:

    >>> a, b = 0, 1
    >>> while b < 1000:
    ...     print(b, end=',')
    ...     a, b = b, a+b
    ...
    1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    

CHAPTER
FOUR


MORE CONTROL FLOW TOOLS

更深入控制流程工具

Besides the while statement just introduced, Python knows the usual control flow statements known from other languages, with some twists.
除了刚刚介绍的while语句, Python 学习了常用的控制流程语句从其他的语言, 并有些改变.

4.1 if Statements

4.1 if 语句

Perhaps the most well-known statement type is the if statement. For example:

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More

There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is short for ‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for the switch or case statements found in other languages.

也许最众所周知的语句类型是 if 语句. 比如:

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More

这里可有零个或更多 elif 部分, 并且 else 部分是可选的. 关键字 ‘elif’ 是 ‘else if’ 的缩写, 并且有助于避免过多的缩进. if … elif … elif … 序列是替代其他语言中的 ‘switch case’ 语句.

4.2 for Statements

4.2 for 语句

The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12

Python 的 for 语句有点不同于那些你可能常用的比如 C 或者 Pascal. 而不是总是迭代数字的算术级数(比如 Pascal中), 或由用户来定义迭代步骤和中止条件(如 C), Python 的 for 语句迭代任何序列项目(列表或字符串), 按它们出现在序列中的顺序排列. 例如(没有双关语意)

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12

If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:

>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

如果你需要修改序列在你迭代循环里(例如, 复制所选项目), 建议你先做一个复制(在迭代过程中修改迭代序列不安全, 译注<作死没用复制的,无限循环下去了…>). 迭代序列不会隐式地复制. 切片表示法使这特别方便:

>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

4.3 The range() Function

range() 函数

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions:

>>> for i in range(5):
... print(i, end='')
...
01234

如果你需要迭代一个数字序列, 内置函数 range() 将派上用场. 它会生成算术累进:

>>> for i in range(5):
... print(i, end='')
...
01234

The given end point is never part of the generated sequence; range(10) generates 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the ‘step’):

range(5, 10)5, 6, 7, 8, 9
range(0, 10, 3)0, 3, 6, 9
range(-10, -100, -30)-10, -40, -70

给定终点永远不是生成序列的部分; range(10) 生成 10 个值, 序列项目合法索引长度为10. 也可以让范围从其他数字开始. 或者是指定不同的增量(甚至是负数增量; 有时它也被称为’步长’):

range(5, 10)5, 6, 7, 8, 9
range(0, 10, 3)0, 3, 6, 9
range(-10, -100, -30)-10, -40, -70

译注: range() 函数返回的是一个可迭代对象(类型是对象)而不是列表类型, 所以print(range(5, 10))时不会打印结果, 只有经过list()处理后才会返回列表.

To iterate over the indices of a sequence, you can combine range() and len() as follows:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

为了迭代序列的索引, 你想下面样可以结合 range() 和 len():

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

In most such cases, however, it is convenient to use the enumerate() function, see Looping Techniques.
然而, 在大多情况下, 更方便地是使用 enumerate() 函数, 请查看循环技巧.

A strange thing happens if you just print a range:

>>> print(range(10))
range(0, 10)

In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.
当你打印一个 range 时, 奇怪的事会发生:

>>> print(range(10))
range(0, 10)

在许多方面, range()返回的对象就像它是一个列表一样, 但实际上它不是. 它是一个对象, 这个对象会返回期望序列的连续项目在你迭代它时, 但它不会真的产生一个列表, 从而来节约空间.

We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator. The function list() is another; it creates lists from iterables:

>>> list(range(5))
[0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take iterables as argument.
我们说这样的对象是可迭代的, 也就是说, 适合作为函数和结构体的靶标, 它期望从某些东西中获得连续项直到供应结束. 我们看到 for 语句就是这样的迭代器. 函数 list() 是其中一个; 它可以从可迭代(对象)中创建列表:

>>> list(range(5))
[0, 1, 2, 3, 4]

稍后我们将看到更多函数, 它们返回一个可迭代或把可迭代当做一个参数.

4.4 break and continue Statements, and else Clauses on Loops

4.4 break 与 continue 语句, else 子句在循环中

The break statement, like in C, breaks out of the innermost enclosing for or while loop. Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

break 语句, 和 C 里样, 破坏最里面的封闭 for 或 while 循环. 循环语句可能有 else 子句; 它在循环通过列表耗尽(with for)或条件变为false(with while)而终止时执行, 而不是循环被 break 语句终止时. 下面的循环是一个例证, 它查找质数(素数):

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(是的, 这是一段正确的代码. 注意看: else 子句属于 for 循环, 不是属于 if 语句.)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions. The continue statement, also borrowed from C, continues with the next iteration of the loop:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

当使用循环时, else 子句有更多的共同点和 try 语句的 else 子句比 if 语句做的: try 语句的 else 子句运行在没有异常发生时, 而循环的 else 子句运行在没有 break 发生时. 关于更多的 try 语句和异常, 请看 异常处理. continue 语句, 也是从 C 借鉴的, 继续循环的下一次迭代(忽略本次循环后面的语句, 译注):

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

4.5 pass Statements

4.5 pass 语句

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

>>> while True:
...     pass # Busy-wait for keyboard interrupt (Ctrl+C)
...

pass 语句什么事都不做. 它可以被用于当语法要求有语句但程序要求无行动的时候. 比如:

>>> while True:
...     pass # Busy-wait for keyboard interrupt (Ctrl+C)
...

This is commonly used for creating minimal classes:

>>> class MyEmptyClass:
...     pass
...

这同样地用在创建最小类:

>>> class MyEmptyClass:
...     pass
...

Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:

>>> def initlog(*args):
... pass # Remember to implement this!
...

另一个地方, pass 可以被用作一个占位为一个函数或条件体在你处理新代码时, 允许你保持思考在更多的抽象层级. pass 是默默地被忽略:

>>> def initlog(*args):
...     pass # Remember to implement this!
...

4.6 Defining Functions

4.6 定义函数

We can create a function that writes the Fibonacci series to an arbitrary boundary:

>>> def fib(n): # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

我们可以建一个函数来写出斐波那契堆在任意的边界:

>>> def fib(n): # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.
关键词 def 引入函数的定义. 它后面必须跟函数名和带括号形式参数列表. 函数体语句从下一行开始, 而且必须是缩进的.

The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or docstring. (More about docstrings can be found in the section Documentation Strings.) There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it’s good practice to include docstrings in code that you write, so make a habit of it.
函数体的第一个语句可以是可选的字符串文本; 这些字符串文本是函数的文档字符, 或文档字符串. (更多关于文档字符串可以被发现在文档字符串部分.) 这里有些工具, 使用 docstrings 去自动生成在线的或打印的文档, 或是让用户通过代码交互式浏览; 它是好的实践包含在你写的文档, 所以让它成为一个习惯吧.

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.
函数的执行会引入了一个新的符号为了函数的局部变量. 更确切地说, 所有变量赋值在函数中存储值到局部符号表; 而变量引用首先在局部符号表中查找, 然后是包含函数的局部符号表, 再然后是全局符号表, 最后是内建名表. 因此, 全局变量不能被直接地通过函数赋值(除非命名在全局语句中), 虽然它们可能被引用

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object).3 When a function calls another function, a new local symbol table is created for that call.
函数引入的调用实际参数(实参)在调用的函数局部符号表里当它被调用时; 因此, 实参是通过值的调用来传递的(这里的值永远是对象引用, 而不是对象的值). 当一个函数调用另一个函数时, 一个新的本地符号表就会被生成在调用时.

A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

函数定义引入函数名称在当前符号表. 函数名的值有一个类型, 这个类型被解释器认定为一个用户自定义函数. 这个值可以被赋值给其他名称, 这个名称后面也可以被当做一个函数. 这提供常用的重命名机制:

>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a return statement do return a value, albeit a rather boring one. This value is called None (it’s a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using print():

>>> fib(0)
>>> print(fib(0))
None

如果你来自其他语言, 你可能反对说 fib 不是一个函数而是一个过程因为它不返回一个值. 事实上, 甚至没有 return 语句的函数也会返回一个值, 尽管是一个烦人的家伙. 这个值被称为 None (它是内建名称). 写入值None通常会被解释器忽略, 如果它是唯一写入的值. 如果你真的想看可以使用 print():

>>> fib(0)
>>> print(fib(0))
None

It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:

>>> def fib2(n): # return Fibonacci series up to n
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a) # see below
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

这是很简单的去写一个返回斐波那契堆数列表的函数, 而不是打印它:

>>> def fib2(n): # return Fibonacci series up to n
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a) # see below
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

This example, as usual, demonstrates some new Python features:

  • The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.
  • The statement result.append(a) calls a method of the list object result. A method is a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, see Classes) The method append() shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to result = result + [a], but more efficient.
    这个例子, 和往常样, 演示了一些新 Python 特性:
  • return 语句从函数返回一个值. 返回没有表达式参数则返回 None. 函数结尾 Falling off 也返回 None.
  • 语句 result.append(a) 调用一个列表对象 result 的方法. 方法是’属于’一个对象的函数, 它被命名为 obj.name, 这里的 obj 是一些对象(也可能是表达式), 方法名是方法对象类型定义的名称. 不同类型定义着不同的方法. 不同类型的方法可能有相同的名称但不会造成歧义. (它可能来定义你自己个人的对象类型和方法, 使用类, 详见类) 例中展示的 append() 方法是由列表对象定义的; 它添加新的元素到列表的后面. 在示例中, 它等同于 result = result + [a], 但是更高效.

4.7 More on Defining Functions

4.7 深入了解定义函数

It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.
定义函数和数个变量参数也是可以的. 这里有三种形式, 他们也可以混用.

4.7.1 Default Argument Values

4.7.1 默认参数值

The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:

def ask_ok(prompt, retries=4, reminder='Please try again!'):while True:ok = input(prompt)if ok in ('y', 'ye', 'yes'):return Trueif ok in ('n', 'no', 'nop', 'nope'):return Falseretries = retries - 1if retries < 0:raise ValueError('invalid user response')print(reminder)

最常用的形式是, 指定默认值给一个或更多参数. 这样创建一个函数允许在调用时可以少几个参数比在定义它时. 比如:

def ask_ok(prompt, retries=4, reminder='Please try again!'):while True:ok = input(prompt)if ok in ('y', 'ye', 'yes'):return Trueif ok in ('n', 'no', 'nop', 'nope'):return Falseretries = retries - 1if retries < 0:raise ValueError('invalid user response')print(reminder)

This function can be called in several ways:

  • giving only the mandatory argument: ask_ok('Do you really want to quit?')
  • giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
  • or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

这个函数可以用以下几种方式调用:

  • 只给一个强制性参数: ask_ok('Do you really want to quit?')
  • 再给一个可选参数: ask_ok('OK to overwrite the file?', 2)
  • 或是给全部参数: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value. The default values are evaluated at the point of function definition in the defining scope, so that:

i = 5
def f(arg=i):print(arg)
i = 6
f()

will print 5.

该示例还介绍了关键字 in. 它测试一个序列是否包含某些值. 默认值被赋值在定义函数时的定义范围里, 如下:

i = 5
def f(arg=i):print(arg)
i = 6
f()

将会输出 5.

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

def f(a, L=[]):L.append(a)return Lprint(f(1))
print(f(2))
print(f(3))

This will print

[1]
[1, 2]
[1, 2, 3]

重要注意: 默认值只被赋值一次. 这造成异议, 当默认值是个易变的对象比如一个列表, 字典, 或是大多数类的实例.

def f(a, L=[]):L.append(a)return Lprint(f(1))
print(f(2))
print(f(3))

将打印:

[1]
[1, 2]
[1, 2, 3]

If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

def f(a, L=None):if L is None:L = []L.append(a)return L

如果你不想默认值被共享在后续的调用中, 你可以像下面样写函数:

def f(a, L=None):if L is None:L = []L.append(a)return L

4.7.2 Keyword Arguments

4.7.2 关键字参数

Functions can also be called using keyword arguments of the form kwarg=value. For instance, the following function:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):print("-- This parrot wouldn't", action, end=' ')print("if you put", voltage, "volts through it.")print("-- Lovely plumage, the", type)print("-- It's", state, "!")

accepts one required argument (voltage) and three optional arguments (state, action, and type). This function can be called in any of the following ways:

parrot(1000) # 1 positional argument
parrot(voltage=1000) # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword

but all the following calls would be invalid:

parrot() # required argument missing
parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument
parrot(110, voltage=220) # duplicate value for the same argument
parrot(actor='John Cleese') # unknown keyword argument

函数也可以用关键字参数与调用, 形如 kwarg=value. 例如, 下面的函数:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):print("-- This parrot wouldn't", action, end=' ')print("if you put", voltage, "volts through it.")print("-- Lovely plumage, the", type)print("-- It's", state, "!")

接受一个 required 参数(voltage)和三个可选参数(state, action, and type). 这个函数可以被以下任意一种方式调用:

parrot(1000) # 1 positional argument #1个位置参数
parrot(voltage=1000) # 1 keyword argument   # 一个关键词参数
parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments # 2 关键词参数
parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments # 2 关键词参数 位置可以不定
parrot('a million', 'bereft of life', 'jump') # 3 positional arguments # 3 位置参数, 位置是要对应的
parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword  # 1位置, 1关键词, 前者位置须对应

但是下面的调用会是无效的:

parrot() # required argument missing  # 缺少必须参数
parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument # 无关键词参数在关键词参数前 或是positional argument follows keyword argument
parrot(110, voltage=220) # duplicate value for the same argument  # 参数有重复值
parrot(actor='John Cleese') # unknown keyword argument # 不知道哪里的关键词参数 nexpected keyword argument

In a function call, keyword arguments must follow positional arguments. All the keyword arguments passed must match one of the arguments accepted by the function (e.g. actor is not a valid argument for the parrot function), and their order is not important. This also includes non-optional arguments (e.g. parrot(voltage=1000) is valid too). No argument may receive a value more than once. Here’s an example that fails due to this restriction:

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function() got multiple values for keyword argument 'a'

函数调用中, 关键词参数必须跟在位置参数后. 所有的关键字参数传递必须匹配一个函数接受的参数(例, actor 不是有效的参数对于 parrot 函数), 而他们的顺序并不那么重要. 这也包括非可选(必须, 译注)参数(例, parrot(voltage=1000) 也是无效的). 没有参数可以获取超过一次的值. 这里有一个例子, 它基于这个限制:

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form **name is present, it receives a dictionary (see typesmapping) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) For example, if we define a function like this:

def cheeseshop(kind, *arguments, **keywords):print("-- Do you have any", kind, "?")print("-- I'm sorry, we're all out of", kind)for arg in arguments:print(arg)print("-" * 40)for kw in keywords:print(kw, ":", keywords[kw])

当形如**name最后的形参被引入时, 它接受一个字典(参见typesmapping), 包含所有的关键字参数除了那些对应于形参的. 这里也有可能包含形如 *name 的形参(描述在下一小节中), 它接受一个元组, 包含除形参列表外的所有参数. (*name 必须在 **name之前.) 举例, 如下我们像这样定义函数:

def cheeseshop(kind, *arguments, **keywords):print("-- Do you have any", kind, "?")print("-- I'm sorry, we're all out of", kind)for arg in arguments:print(arg)print("-" * 40)for kw in keywords:print(kw, ":", keywords[kw])

It could be called like this:

cheeseshop("Limburger", "It's very runny, sir.","It's really very, VERY runny, sir.",shopkeeper="Michael Palin",client="John Cleese",sketch="Cheese Shop Sketch")

and of course it would print:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

Note that the order in which the keyword arguments are printed is guaranteed to match the order in which they were provided in the function call.

它可以像这样被调用:

cheeseshop("Limburger", "It's very runny, sir.","It's really very, VERY runny, sir.",shopkeeper="Michael Palin",client="John Cleese",sketch="Cheese Shop Sketch")

当然它会出现如下打印:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

注意, 关键字参数打印的顺序是保证于匹配函数调用提供的顺序.(可以通过字典 keys() 方法来排序)

4.7.3 Arbitrary Argument Lists

4.7.3 随意参数列表

Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see Tuples and Sequences). Before the variable number of arguments, zero or more normal arguments may occur.

def write_multiple_items(file, separator, *args):file.write(separator.join(args))

最后, 最不常用的选项是指定这个函数可以调用任意数个参数. 这些参数将被包装到一个元组(参见元组和序列). 在这个可变参数前, 可以有另个或多个普通参数.

def write_multiple_items(file, separator, *args):file.write(separator.join(args))

Normally, these variadic arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.

>>> def concat(*args, sep="/"):
...     return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

通常, 这可变参数是形参最后面的, 因为它们打包所有其余的输入参数传递给函数. 任何出现*args参数后面的形参都是 ‘keyword-only’ 参数(关键字参数), 意为着它们只能被用作关键字而非位置参数.

>>> def concat(*args, sep="/"):
...     return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

4.7.4 Unpacking Argument Lists

4.7.4 拆分参数列表

The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:

>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]

相反的情况会出现: 当参数已经是一个列表或元组, 但需要被拆分给需要单独位置参数的函数调用. 例如, 内置函数 range() 期望单独的开始和结束参数. 如果它们不是可用独立的, 写函数调用时用 * 操作符去拆分出列表或元组参数:

>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]

In the same fashion, dictionaries can deliver keyword arguments with the **-operator:

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

同样地, 字典可以被拆解为关键字参数通过操作符 **

4.7.5 Lambda Expressions

4.7.5 λ 表达式

Small anonymous functions can be created with the lambda keyword. This function returns the sum of its two arguments: lambda a, b: a+b. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope:

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

小的匿名函数可以被创建用 lambda 关键字. 这个函数返回两个参数的和: lambda a, b: a+b. λ 函数可以用在那些函数对象需要的地方. 它们被语法限制在一个单一表达式. 语义上, 它们只是语法糖对于一个正常函数定义. 就像嵌套函数定义, λ 函数可以从外部作用域引用变量:

>>> def make_incrementor(n):
...     return lambda x: x + n  # 这里的 n 就是使用的 λ 外部参数, x 是他自己的参数
...
>>> f = make_incrementor(42)    # 返回的结果就是 λ 函数: lambda x: x + n
>>> f(0)                        # 所以  f(0), f(1) 分别加0, 1
42
>>> f(1)
43
>>> make_incrementor(103)(109)     # make_incrementor(103)(109) 也可行, 结果为 103+109
212

The above example uses a lambda expression to return a function. Another use is to pass a small function as an argument:

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

上面的例子使用 λ 表达式返回一个函数. 另一个用法是传递一个小函数作为参数:

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])   #  λ 返回列表的第二个元素
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')] # 结果是将列表第二个元素排到最后, 为啥是这样.... list.sort 看不懂(T^T)

4.7.6 Documentation Strings

4.7.6 文档字符串

Here are some conventions about the content and formatting of documentation strings.
这里有些惯例关于文档字符串的内容和格式

The first line should always be a short, concise summary of the object’s purpose. For brevity, it should not explicitly state the object’s name or type, since these are available by other means (except if the name happens to be a verb describing a function’s operation). This line should begin with a capital letter and end with a period.
第一行总是对象宗旨的短小、简洁摘要. 为了简洁, 它不应该明确地声明对象的名称或类型, 因为这些可能改变被其他的方法(除非这名称正好是描述函数操作的动词). 这一行应该开始于一个大写字母, 结束于一个句号.

If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object’s calling conventions, its side effects, etc.
如果文档字符串里有更多行, 第二行应该是空行, 视觉上分开摘要和其余的说明. 接下来的行应该是一段或多段说明对象的调用约定及副作用等等.

The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can’t use the first line since it is generally adjacent to the string’s opening quotes so its indentation is not apparent in the string literal.) Whitespace “equivalent” to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).
Python 解析器不会从多行字符串文本去除缩进, 所以, 如果需要, 处理文本的工具必须去除缩进. 这么做来遵循惯例. 第一个非空行之后的第一行字符串确定整个文档字符串缩进. (我们不使用第一行, 因为它通常紧邻字符串开始的引号, 所以它的缩进是不明显的在文本字符串中.) 空白"等量"的缩进是而后从所有行字符串的开始去除. 缩进较少的行不应该出现, 但如果它们出现了, 所有开头的空白应该被去除. 空白的等量应该被测试在后面的制表符扩展(通常是8个空格).

Here is an example of a multi-line docstring:

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.No, really, it doesn't do anything.

这里是一个多行 docstring 的示例:

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.No, really, it doesn't do anything.

译注: __doc__ 是 python 函数内置魔术属性, 存储函数说明或注释(即第一个未被赋值的字符串)

4.7.7 Function Annotations

4.7.7 函数注释

Function annotations are completely optional metadata information about the types used by user-defined functions (see PEP 3107 and PEP 484 for more information).
函数注释是完全可选的关于用户自定义函数类型使用的元数据信息(参见 PEP 3107 和 PEP 484 有更多信息).

Annotations are stored in the __annotations__ attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are defined by a literal ->, followed by an expression, between the parameter list and the colon denoting the end of the def statement. The following example has a positional argument, a keyword argument, and the return value annotated:

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'

注释存储在 __annotations__ 函数属性里作为一个字典, 而且对其他部分的函数没有影响. 参数注释是定义在参数名后冒号的后面, 接表达式去表示注释值. 返回注释是定义在文本 ->后 , 接表达式, 在参数列表和表示def语句结尾的冒号之间. 下面的例子有一个位置参数, 一个关键字参数, 然后返回注释值:

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'

4.8 Intermezzo: Coding Style

4.8 间奏曲: 编码风格

Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about coding style. Most languages can be written (or more concise, formatted) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that.
现在你已经可以写更长, 更复杂的 Python 片段了, 这是好时机去讨论编码风格. 大多数语言可以被不同的风格写出(或更简明地说, 格式化); 有些可能比其他的更加具可读性. 使其他人容易读懂你的代码总是好的想法, 而且采用漂亮的代码风格对此有很==大帮助

For Python, PEP 8 has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; here are the most important points extracted for you:

  • Use 4-space indentation, and no tabs.
    4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, and are best left out.
  • Wrap lines so that they don’t exceed 79 characters.
    This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.
  • Use blank lines to separate functions and classes, and larger blocks of code inside functions.
  • When possible, put comments on a line of their own.
  • Use docstrings.
  • Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).
  • Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classesfor more on classes and methods).
  • Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.
  • Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.

在 Python, PEP 8已经有了大多数项目遵循的风格指南; 它提倡一种高可读而且视觉友好的编码风格. 每个 Python 开发者都应该在某些时候阅读它, 这里有最重要的几点摘要给你:

  • 用 4 个空格缩进, 而非制表符.
    4 个空格是在小缩进(允许更大的嵌套深度)和大缩进(便于阅读)之间很好的折中. 制表符引发混乱, 最好舍去.
  • 行宽最好不要超过 79 个字符.
    这帮助用户使用小尺寸显示器, 也使得数个源码文件可以并排在大显示器上.
  • 使用空白行去分隔函数和类, 或者是函数里的大块代码.
  • 若可能, 将注释放在它们自己独占的一行.
  • 使用文档字符串(docstrings).
  • 使用空格在操作符两侧和逗号后面, 但不直接在括号结构内侧: a = f(1, 2) + g(3, 4). (即不要在括号内侧, 译注)
  • 类和函数命名一致, 惯例是, 类用大驼峰(CamelCase), 函数和方法用小写字母和下划线(lower_case_with_underscores). 总是用 self 作为第一个反复参数与名(详见类和方法的初识类).
  • 不要使用花俏的编码, 如果你的编码意在国际化的环境中. Python 的默认是 UTF-8, 甚至朴实的 ASCII 在任何情况下工作得最好.
  • 同样地, 不要使用非 ASCII字符作为标识符, 在只有最轻微的机会, 人们说着不同的语言会阅读或维护代码.

CHAPTER
FIVE


DATA STRUCTURES

数据结构

This chapter describes some things you’ve learned about already in more detail, and adds some new things as well.

5.1 More on Lists

5.1 更多关于列表的内容

The list data type has some more methods. Here are all of the methods of list objects:
列表数据类型有许多方法. 这里是列表对象的所有方法:

list.append(x)
Add an item to the end of the list. Equivalent to a[len(a):] = [x].
list.append(x)
添加一个项目到列表最后徐. 等价于 a[len(a):] = [x].

list.extend(iterable)
Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.
list.extend(iterable)
扩展列表通过从可迭代对象添加所有项目. 等价于 a[len(a):] = iterable.

list.insert(i, x)
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
list.insert(i, x)
插入项目在指定位置. 第一个参数是要插入其前面的元素索引, 所以 a.insert(0, x) 插在列表最前面, 而 a.insert(len(a), x) 等价于 a.append(x).

list.remove(x)
Remove the first item from the list whose value is x. It is an error if there is no such item.
list.remove(x)
从列表中移除第一个值为 x 的项目. 如果没有找到项目将报错.

list.pop([i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)
list.pop([i])
移除列表指定位置的项目, 然后返回它. 若没有指定索引, a.pop() 将移除和返回列表最后一个项目. (方法里方括号包含的 i 表示这个参数是可选的, 不是让你再那个地方键入方括号. 你将经常看到这个符号在 Python 库手册里.)

list.clear()
Remove all items from the list. Equivalent to del a[:].
list.clear()
清除列表所有项目. 等价于去删除, 即 a[:].

list.index(x[, start[, end]])
Return zero-based index in the list of the first item whose value is x. Raises a ValueError if there is no such item. The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list.
The returned index is computed relative to the beginning of the full sequence rather than the start argument.
list.index(x[, start[, end]])
返回从零开始 在列表中第一个值为 x 项目的索引. 如果没有找到项目则引发一个异常. 可选项参数 start 和 end 被解读做切片符号, 是用来限制搜索在列表的一个特定子序列.
返回的索引相对整个序列的开始计算的, 而不是这个 start 参数.

list.count(x)
Return the number of times x appears in the list.
list.count(x)
返回项目 x 在列表中出现的次数.

list 计总数用方法: __len__(), 或者是: len(list)

list.sort(key=None, reverse=False)
Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation)
list.sort(key=None, reverse=False)
对列表就地(这个 in place 是啥意思T^T)就行排序(参数可被用作排序规则, 详细说明请见 sort())

list.reverse()
Reverse the elements of the list in place.
list.reverse()
就地颠倒列表的元素. (就只是反过来, 不做排序处理)

list.copy()
Return a shallow copy of the list. Equivalent to a[:].
list.copy()
返回一个列表的拷贝. 等级于 a[:].

An example that uses most of the list methods:

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4) # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'

You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None.4 This is a design principle for all mutable data structures in Python.

下面是列表最常用的方法:

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4) # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'

你可能注意到, 像 insert, remove 或 sort 这些方法只修改列表没有返回值打印 —— 它们返回默认值 None.4 这是 Python 所有易变数据结构的设计原则.

5.1.1 Using Lists as Stacks

5.1.1 使用列表作为堆栈

The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop() without an explicit index. For example:

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

列表的方法是的它很容易去使列表作为一个堆栈, 这最后添加的元素是最新取回元素(即’后进先出’). 添加项目到堆栈顶部使用 append(). 从堆栈顶部取回项目使用没有明确索引的 pop(). 示例:

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]

5.1.2 Using Lists as Queues

5.1.2 用列表作为队列

It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).
用列表作为一个队列也是很容易的, 这最先添加的元素最先被取回(即’先进先出’); 然而, 列表在这个目的上效率不高. 而添加和抛出从列表尾部是很快的, 完成从列表开始处的插入和抛出是比较慢的(因为其他的所有元素都必须被一个个地移动).

To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

为了实现一个队列请使用 collections.deque, 它被设计去快速地从首尾两端添加和抛出. 示例:

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

5.1.3 List Comprehensions

5.1.3 列表推导

List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition. For example, assume we want to create a list of squares, like:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

列表推导提供了一个简明的方式去创建列表. 常见的应用程序是创建新的列表, 其中每个元素是应用于另一个序列的每个成员与迭代的一些操作的结果, 或通过满足特定条件的元素创建一个子序列. 比如, 假设我们想创建如下的列表序列:

>>> squares = []
>>> for x in range(10):
...     squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Note that this creates (or overwrites) a variable named x that still exists after the loop completes. We can calculate the list of squares without any side effects using:

squares = list(map(lambda x: x**2, range(10)))

or, equivalently:

squares = [x**2 for x in range(10)]

which is more concise and readable.
请注意, 这会创建(或覆盖)一个名为x的变量, 该变量在循环完成后仍然存在. 我们可以计算 squares 没有任何副作用, 这样使用:
或, 等价于:

squares = [x**2 for x in range(10)]

这种方式更简明易读.

A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

and it’s equivalent to:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...     if x != y:
...     combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Note how the order of the for and if statements is the same in both these snippets.

列表推导由括号, 括号中包含一个表达式, 后跟一个for子句, 然后是零个或多个for或if子句组成. 结果是一个列表, 由表达式依据其后面的 for 和 if 子句上下文计算而来的结果构成.

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

它等价于:

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

请注意这两个片段中 for 和 if 语句的顺序是如何相同的.

If the expression is a tuple (e.g. the (x, y) in the previous example), it must be parenthesized.

>>> vec = [-4, -2, 0, 2, 4]
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # call a method on each element
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # the tuple must be parenthesized, otherwise an error is raised
>>> [x, x**2 for x in range(6)]File "<stdin>", line 1, in <module>[x, x**2 for x in range(6)]^
SyntaxError: invalid syntax
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

如果表达式是元组(例如, 上例中的(x, y)), 它必须是括号内的.

>>> vec = [-4, -2, 0, 2, 4]
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # call a method on each element
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # the tuple must be parenthesized, otherwise an error is raised  # 元组必须在括号里, 否则会报错.
>>> [x, x**2 for x in range(6)]File "<stdin>", line 1, in <module>[x, x**2 for x in range(6)]^
SyntaxError: invalid syntax
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

List comprehensions can contain complex expressions and nested functions:

>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

列表推导可以包含复杂的表达式和嵌套的函数:

>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']

5.1.4 Nested List Comprehensions

5.1.4 嵌套列表推导

The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.
列表推导初始表达式可以是任何表达式, 包括其他的列表推导.

Consider the following example of a 3x4 matrix implemented as a list of 3 lists of length 4:

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]

研究下面例子, 一个 3x4 矩阵, 由3个长度为4的列表组成的列表:

>>> matrix = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]

The following list comprehension will transpose rows and columns:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

下面的列表推导将颠倒行和列:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

As we saw in the previous section, the nested listcomp is evaluated in the context of the for that follows it, so this example is equivalent to:

>>> transposed = []
>>> for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

which, in turn, is the same as:

>>> transposed = []
>>> for i in range(4):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

正如我们在上一节中看到的那样, 嵌套的listcomp在其后面的for的上下文中进行赋值, 所以上面的例子等价于:

>>> transposed = []
>>> for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

反过来来说, 它与以下相同:

>>> transposed = []
>>> for i in range(4):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

In the real world, you should prefer built-in functions to complex flow statements. The zip() function would do a great job for this use case:

>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]

See Unpacking Argument Lists for details on the asterisk in this line.

实际上, 你应该比较喜欢内置函数去组成复杂流程语句. zip() 函数可以很好地处理这个用例:

>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]   # 只是里面由列表变成元组, * 参数的作用

关于行中星号的详细参见拆分参数列表

5.2 The del statement

5.2 del 语句

There is a way to remove an item from a list given its index instead of its value: the del statement. This differs from the pop() method which returns a value. The del statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del can also be used to delete entire variables:

>>> del a

Referencing the name a hereafter is an error (at least until another value is assigned to it). We’ll find other uses for del later.

这是一个方式, 从列表中移除给定索引而不是值的项目: del 语句. 不同于 pop() 方法. del 语句既可以删除列表的一段切片(这也就是切边为浅复制的表现, 译注), 也可以清空整个列表(我们之前通过将一个空列表分配给切片来做到的). 示例:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]

del 也可以用来删除整个变量:

>>> del a

以后引用这个名称会报错(直到其他值赋值到它). 稍后我们将发现 del 的其他用法.

5.3 Tuples and Sequences

5.3 元组和序列

We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples of sequence data types (see typesseq). Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple.
A tuple consists of a number of values separated by commas, for instance:

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

我们已经看到, 列表和字符串有很多共同的属性, 比如索引和切片操作. 他们是序列数据类型(参见 typesseq)的两个实例. 因为 Python 是不断进化的语言, 所以其他的序列数据类型可能被加入. 这里是另一个标准序列数据类型: 元组. 元组逗号分隔的许多值组成, 示例:

>>> t = 12345, 54321, 'hello!'  # 定义时不一定要括号
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:     # 元组可以嵌套
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:     # 元组是不可变的
... t[0] = 88888
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:  可以包含易变对象
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

As you see, on output tuples are always enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression). It is not possible to assign to the individual items of a tuple, however it is possible to create tuples which contain mutable objects, such as lists.
正如你所见, 输出的元组总是被括弧包裹着, 这是为了便于正确解释嵌套元组; 而他们在被输入时有或没有两边的括弧都行, 虽然通常括号是必要的(如果元组是大量表达式的一部分). 复制给元组的私有项目是不可能的, 但可以创建包含易变对象的元组, 比如列表

Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are immutable, and usually contain a heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of namedtuples). Lists are mutable, and their elements are usually homogeneous and are accessed by iterating over the list.
虽然元组看上去可能类似于列表, 但他们经常用在不同的情况, 也是为了不同的目的. 元组是不可变的, 并且通常包含通过解包(详见后续章节)或索引(或甚至可以是属性, 在已 namedtuples 的情况下)访问的异构元素序列. 列表是易变的, 而且他们的元素通常是同质的, 通常通过迭代访问列表.

A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For example:

>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)

一个特别的问题是元组结构包含 0 或 1 个项目时: 语法上有些额外的怪癖去适应它们. 空元组通过一空括弧来构造, 只有一个项目的元组是通过值后面跟一个逗号来构造(括单个值在括弧里是不够的). 丑, 但是高效(_). 示例:

>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
>>> singlestr = ('hello') # 只有括弧, 就是字符串
>>> len(singlestr)
5
>>> singlestr
'hello'

The statement t = 12345, 54321, ‘hello!’ is an example of tuple packing: the values 12345, 54321 and ‘hello!’ are packed together in a tuple. The reverse operation is also possible:

t = 12345, 54321, 'hello!'
>>> x, y, z = t
>>> z
'hello!'
>>> y
54321
>>> x
12345

语句 t = 12345, 54321, 'hello!' 是元组打包的一个例子: 值 12345, 54321 和 ‘hello!’ 是一起打包进元组的. 逆操作也是可以的(即解包元组, 译注):

t = 12345, 54321, 'hello!'
>>> x, y, z = t
>>> z
'hello!'
>>> y
54321
>>> x
12345

This is called, appropriately enough, sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires that there are as many variables on the left side of the equals sign as there are elements in the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.
这就足够恰当地称为序列拆包, 而且适用于任何右侧序列. 序列拆包要求有足够多的变量在等号左侧, 接受序列里的元素. 请注意, 多重赋值真的只是元组打包和序列解包的一个组合.

5.4 Sets

5.4 集合

Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.
Python 还包含一个数据类型–集合. 集合是一个无重复元素的无序汇集. 基本用法包括成员测试和消除重复条目. 集合对象还支持数学运算, 像是并集, 交集, 差集和对称差.

Curly braces or the set() function can be used to create sets. Note: to create an empty set you have to use set(), not {}; the latter creates an empty dictionary, a data structure that we discuss in the next section.
Here is a brief demonstration:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing
True
>>> 'crabgrass' in basket
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b
{'a', 'c'}
>>> a ^ b # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

大括号或是函数 set() 可以用来创建集合. 注意, 创建空集合只能用 set(), 不能用 {}; 后者用来创建空字典, 它是我们下一节讨论的一种数据结构.
这里有一个简要的示范:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket # fast membership testing   快速成员测试
True
>>> 'crabgrass' in basket
False
>>> # Demonstrate set operations on unique letters from two words
>>> # 演示集合操作来自两个单词的唯一字母
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # letters in a but not in b  差集(相对)
{'r', 'd', 'b'}
>>> a | b # letters in a or b or both  并集
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # letters in both a and b    交集
{'a', 'c'}
>>> a ^ b # letters in a or b but not both  对差集
{'r', 'd', 'b', 'm', 'z', 'l'}

Similarly to list comprehensions, set comprehensions are also supported:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}

类似列表推导, 集合也是支持推导:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}

5.5 Dictionaries

5.5 字典

Another useful data type built into Python is the dictionary (see typesmapping). Dictionaries are sometimes found in other languages as “associative memories” or “associative arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() and extend().
Python 另一个常用的内置数据类型是字典(参见typesmapping). 字典有时候被发现在其他语言里叫作"关联内存"或"关联数组". 不像索引是一系列数字的序列, 字典的索引是键, 它可以是任何不可变类型; 字符串和数字总是作为这个键. 元组也可用作键, 若他们只包含字符串, 数字, 或元组; 如果元组包含任何或直接或间接的可变对象, 它就不能被用作键. 你不能用列表作为键, 因为列表可以被就地修改, 通过使用索引赋值, 切片赋值, 或想 append() 和 extend() 这样的方法.

It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {}. Placing a commaseparated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.

The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.
最好的想法是将字典当做一个键:值对的无序集合, 这就要求键是不可重复的(在一个字典里). 一对花括号可以创建空的字典: {}. 放置一组逗号分开键:值对在花括号里, 当初始添加键:值`对到字典时; 这也是字典输出的写作方式.

Performing list(d.keys()) on a dictionary returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just use sorted(d.keys()) instead).4 To check whether a single key is in the dictionary, use the in keyword.
对字典执行 list(d.keys()) 返回一个字典所用的全部键且随意排序的列表(若要排序, 使用 sorted(d.keys()) 替换即可). 4 要检查单个键是否在字典里, 使用 in 关键字.

Here is a small example using a dictionary:

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

这里有些使用字典的小例子:

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False

The dict() constructor builds dictionaries directly from sequences of key-value pairs:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}

函数 dict 从有序的键值对直接构建字典:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])  # dict expected at most 1 arguments 所以用列表框起来
{'sape': 4139, 'jack': 4098, 'guido': 4127}

5.6 Looping Techniques

5.6 循环技巧

When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

当循环遍历词典时, 使用 items() 方法同时取回键和对应值.

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the enumerate() function.

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe

当循环遍历序列时, 位置索引和对应值可以同时被取回用 enumerate() 函数.

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for i,v in enumerate(knights):
...     print(i, v)
...
0 gaallahad
1 robin

译注: enumerate() 处理字典后获取的是键的位置索引和对应键, 通 list(d.keys()) 样.

To loop over two or more sequences at the same time, the entries can be paired with the zip() function.

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.

要同时循环两个或更多序列, 可以使用函数 zip() 来整体打包.

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.

zip() 打包到最小序列为止, 也就是哪个序列小, 遍历的长度就是那个序列的长度

To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the reversed() function.

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
97531

要逆向遍历一个序列, 先正向定序这个序列, 然后调用 reversed() 函数.

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
97531

To loop over a sequence in sorted order, use the sorted() function which returns a new sorted list while leaving the source unaltered.

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

要排序遍历序列, 使用函数 sorted() 返回一个新的排序后列表, 它不会影响原列表的顺序.

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

译注: 也没了重复项.

It is sometimes tempting to change a list while you are looping over it; however, it is often simpler and safer to create a new list instead.

>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]

有些时候你要临时改变列表在遍历它时; 不过, 通常创建新列表更简单, 更安全.

>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
...     if not math.isnan(value):
...     filtered_data.append(value)
...
>>> filtered_data
[56.2, 51.7, 55.3, 52.5, 47.8]

5.7 More on Conditions

5.7 更多关于条件(控制)

The conditions used in while and if statements can contain any operators, not just comparisons.
while 和 if 语句用的条件可以包含任何操作符, 不仅仅是比较.

The comparison operators in and not in check whether a value occurs (does not occur) in a sequence. The operators is and is not compare whether two objects are really the same object; this only matters for mutable objects like lists. All comparison operators have the same priority, which is lower than that of all numerical operators.
比较符 in 和 not in 检查值是否在序列里. 操作符 is 和 not is 比较两个对象是否真的是同一个对象; 这对像列表这样的可变对象很重要. 所有的比较操作符有想同的优先级, 且他们都低于所有算术操作符.

Comparisons can be chained. For example, a < b == c tests whether a is less than b and moreover b equals c.
比较可以链接. 比如, a < b == c 测试 a 是否小于 b, 且 b 等于 c.

Comparisons may be combined using the Boolean operators and and or, and the outcome of a comparison (or of any other Boolean expression) may be negated with not. These have lower priorities than comparison operators; between them, not has the highest priority and or the lowest, so that A and not B or C is equivalent to (A and (not B)) or C. As always, parentheses can be used to express the desired composition.
比较可能包含用逻辑操作符 and 和 or, 而且其他比较的结果()也可以用 not 来否定. 这些的优先级比比较操作符更低; 在它们之间, not 有最高或最低的优先级, 所以 A and not B or C 是等价于 (A and (not B)) or C. 总之, 括弧可以被用来表达所期望的比较.

The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.
布尔运算符 and 和 or 是所谓的短路运算符: 它们的参数从左到右进行评估, 一旦确定结果, 评估就会停止. 比如, 如果 A and C 为真, 但 B 为假, 那么 A and B and C 不会评估表达式C. 作为一般的值而非布尔值使用时, 短路操作符的返回值是最后的参数.(感觉应该是最近一个…译注)

It is possible to assign the result of a comparison or other Boolean expression to a variable. For example,

>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'

可以赋值比较或布尔表达式的结果给一个变量. 示例,

>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'

Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.
注意, 在 Python 不像 C 中, 赋值不能出现在表达式内. C 程序员可能对它发牢骚, 但是避免一类问题在 C 出现, 键入 = 在表达式中应该用 == 替换的时.

5.8 Comparing Sequences and Other Types

比较序列和其他类型

Sequence objects may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted. If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode code point number to order individual characters. Some examples of comparisons between sequences of the same type:

(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)

序列对象可以用来与其他同序列类型的对象进行比较. 比较使用词典排序: 首先, 前两个项目进行比较, 如果它们不同就决定出比较的结果; 如果相同就比较接下来的两个项目, 以此类推, 直到两种序列比较. 如果要比较的两个项本身是相同类型的序列, 则递归地执行字典比较. 如果两个序列的所有项目相等, 则认为序列相等. 如果一个序列是另一个序列的初始子序列, 较短的一个序列就小于另一个. 字符串的词典排序使用 Unicode 代码点编码来排序单个字符. 这里有一些同类型序列间比较的例子:

(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)

Note that comparing objects of different types with < or > is legal provided that the objects have appropriate comparison methods. For example, mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc. Otherwise, rather than providing an arbitrary ordering, the interpreter will raise a TypeError exception.
注意, 比较两个不同类型的对象用 < 或 > 是合法的, 这些对象要提供合适的比较方法. 例如, 混合数值类型是通过他们的数值来比较的, 所以 0 等于 0.0, 等等. 此外情况, 不会去提供一个随意的结果, 而是解释器抛出一个 TypeError 异常.


  1. Since ** has higher precedence than -, -3**2 will be interpreted as -(3**2) and thus result in -9. To avoid this and get 9, you can use (-3)**2. ↩︎

  2. Unlike other languages, special characters such as \n have the same meaning with both single (’…’) and double ("…") quotes. The only difference between the two is that within single quotes you don’t need to escape " (but you have to escape ') and vice versa ↩︎

  3. Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list). ↩︎

  4. Calling d.keys() will return a dictionary view object. It supports operations like membership test and iteration, but its contents are not independent of the original dictionary – it is only a view. ↩︎ ↩︎ ↩︎ ↩︎

Python Tutorial中英双语对照文档1相关推荐

  1. Python Tutorial中英双语对照文档5

    Python Tutorial中英双语对照文档4 CHAPTER THIRTEEN WHAT NOW? 现在咧? Reading this tutorial has probably reinforc ...

  2. Python Tutorial中英双语对照文档2

    接 Python Tutorial中英双语对照文档1 CHAPTER SIX MODULES 模块 If you quit from the Python interpreter and enter ...

  3. Python Tutorial中英双语对照文档3

    接 Python Tutorial中英双语对照文档2 CHAPTER NINE CLASSES 类 Classes provide a means of bundling data and funct ...

  4. 火车头采集器文章翻译插件(文章标题内容中英双语对照|自动插入相关图片)

    火车头采集器文章翻译插件(文章标题内容中英双语对照|自动插入相关图片) 为了保护接口压力防止被封IP: 请把采集的间隔时间调整为10000~100000 火车头采集器文章翻译插件(文章标题内容中英双语 ...

  5. 彩云小译怎么翻译网页_彩云小译插件,中英双语对照网页翻译,支持视频字幕翻译...

    彩云小译插件应该是谷歌应用商店里最受中文用户欢迎的翻译工具之一. 彩云小译插件包括网页全文翻译和划词翻译两大功能,其中最突出的便是全文双语翻译了. 如果你要问有哪些适合学习外语使用的.比较好的谷歌浏览 ...

  6. php 统计中英混杂word文档字数,wordfrequencycount

    关于 逐行读取 txt 文件,逐行统计词频.使用这种方式可以统计相当大的文本文件. 安装使用 一,下载源码 点击页面中醒目的[克隆/下载] 注册并登录码云 下载 二,下载并安装 PHP 本地运行环境 ...

  7. jna-platform 简介、中文文档、中英对照文档 下载

    jna-platform 文档 下载链接(含jar包.源码.pom) 组件名称 中文-文档-下载链接 中英对照-文档-下载链接 jna-platform-4.1.0.jar jna-platform- ...

  8. javax.servlet-api 简介、中文文档、中英对照文档 下载

    javax.servlet-api 文档 下载链接(含jar包.源码.pom) 组件名称 中文-文档-下载链接 中英对照-文档-下载链接 javax.servlet-api-3.1.0.jar 暂无 ...

  9. easyexcel 简介、中文文档、中英对照文档 下载

    easyexcel 文档 下载链接(含jar包.源码.pom) 组件名称 中文-文档-下载链接 中英对照-文档-下载链接 easyexcel-3.0.5.jar easyexcel-3.0.5-API ...

最新文章

  1. php 求 相似 比,php计算title标题相似比
  2. Delphi资源文件的应用(转)
  3. android Integer类的toString函数的使用
  4. c#在WinForm中重写ProgressBar控件(带%的显示)
  5. cassandra随机获取数据_Cassandra维护最终一致性 和存储机制 分区策略
  6. 一图弄清滴答定时器寄存器 SysTick Registers
  7. MFC开发IM-第二十七篇、如何引入acl,解决Json解析问题
  8. [转]JAVA自动装箱和拆箱
  9. ----发现一款可以代替双手的软件 “按键精灵”
  10. 微信小程序 地图map的坑
  11. PyTorch: Conv2d and ConvTranspose2d
  12. CNGI高校驻地网IPv6用户数量排名
  13. 回首风雨路 笔记本二十年发展史
  14. 论文笔记--Self-Supervised Learning of 3D Human Pose using Multi-view Geometry(利用多视角几何学对三维人类姿势进行自我监督学习)
  15. Crontab中的除号(slash)到底怎么用?(转载)
  16. Java 连接数据库的几种方法
  17. 哈密顿算子及拉普拉斯算子的基本性质及证明
  18. IDEA配置SFTP,SSH非常方便的部署以及定位错误日志
  19. 南开1809计算机应用基础在线作业,【奥鹏】南开21春学期(1709、1803、1809、1903、1909、2003、2009、2103)《计算机应用基础》在线作业1...
  20. 面向 python 小白的贪吃蛇游戏

热门文章

  1. APP攻防——微信小程序解包反编译数据抓包APK资源提取
  2. 日语笔记(3) 动词て形
  3. 近期公司笔试题(4)
  4. 如何查看 ananconda 的环境(虚拟环境)安装包位置
  5. TTY列下的tty?和pts/1,pts/1,pts/2代表的含义
  6. vue 滑动组件_轻巧的Vue滑动组件
  7. 拥有多重人格的他,可能是个裂脑人
  8. 安装MAC系统必备工具
  9. html 用event.keycode控制只能输入小写字母,event.keyCode键码值表 附只能输入特定的字符串代码...
  10. 什么是证券投资基金?