回炉-Python基础教程-1

  |  

摘要: 《Python基础教程》笔记 part1

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


写在前面

【回炉-Python基础教程】系列连载主要回炉我之前看过的一本比较入门但是很系统的 Python 的书。

本书信息:

本书包括Python程序设计的方方面面,主要分为 5 个部分:

  • Python基础知识和基本概念,包括列表、元组、字符串、字典以及各种语句
  • Python相对高级的主题,包括抽象、异常、魔法方法、特性、迭代器、文件处理
  • Python与数据库、网络、C语言等工具结合使用,发挥出Python的强大功能
  • Python程序测试、打包、发布等知识
  • 10个具有实际意义的Python项目的开发过程

本文是《Python基础教程》回炉系列的第一部分中的一些容易忘的点,包括列表、元组、字符串、字典以及控制、循环等各种语句。涉及书中章节 Chap1 ~ Chap5,各章节记录的要点如下:

  • Chap 1 Instant Hacking: The Basics
    • 非十进制数的写法
    • 用户输入
    • 复数
    • 单引号字符串与双引号字符串
    • str和repr
    • Long Strings, Raw Strings and Bytes
      • 1, Long Strings
      • 2, Raw Strings
      • 3, Unicode, Bytes, and Bytearray
  • Chap 2 Lists and Tuples
    • zero index
    • list vs. tuple
    • container
    • Common Sequence Operations
      • slicing shortcut:
    • None, Empty Lists, and Initialization
    • Lists: Python’s Workhorse
      • List method
      • advanced sorting
    • Tuples: Immutable Sequences
  • Chap 3 Working with String
    • Basic String Operations
    • String Formatting: The Short Version
    • String Formatting: The Long Version
      • Replacement Field Names
      • Basic Conversions
      • Width, Precision, and Thousands Separators
      • Signs, Alignment, and Zero-Padding
    • String Methods
  • Chap 4 Dictionaries: Whien Indices Won’t Do
    • Dictionary Uses
    • Creating and Using Dictionaries
      • The dict function
      • Basic Dictionary Operations
      • String Formatting with Dictionaries
      • Dictionary Methods
  • Chap 5 Conditionals, Loops, Some Other Srtatements
    • More About print and import
    • Assignment Magic
      • Sequence Unpacking
      • Chained Assignments
      • Augmented Assignments
    • Blocks: The Joy of Indentation
    • Conditions and Conditional Statements
      • Comparison Operators
    • Loops
      • Some Iteration Utilities
      • Breaking Out of Loops
    • Comprehensions—Slightly Loopy
    • And Three for the Road
      • del
      • Executing and Evaluating Strings with exec and eval

1. 基础知识

非十进制数的写法

以下三个例子分别是十六进制,八进制和二进制。

1
2
3
175 -- 0xAF
8 -- 010
722 -- 0b1011010010

用户输入

1
x = input("x: ") # x 的类型为 str

复数

如果要处理复数,需要 cmath,而不是 math。

1
2
import cmath
cmath.sqrt(-1) # 结果为 1j

如果用 math.sqrt(-1),将会报错 ValueError,结果为 nan(not a number)。

turtle 模块用于画图形输出,是 print 的补充。

单引号字符串与双引号字符串

单引号字符串与双引号字符串是没什么区别的,允许使用两种,因为有时会有需要,例如。

1
2
"Let's go"
'"Heddo world!" she said'

当内外侧引号相同时,内侧需要反斜线,例如:

1
2
'Let\'s go'
"\"Hello world!\" she said"

以上这两种写法都是有用的,例如 'Let\'s say "Hello World!"'

可以通过 concat 的方式避免 backslash 的使用:

1
str1 = "Let's say" '"Hello, World!"'`

str 和 repr

使用str能以合理的方式将值转换为用户能够看懂的字符串。例如,尽可能将特殊字符编码转换为相应的字符。然而,使用repr时,通常会获得值的合法Python表达式表示。

有两种机制可以将值转换为字符串:

(1) str: a class, just like int. With str, you convert a value into a string in some reasonable fashion (以合理的方式将值转换为用户能够看懂的字符串)

(2) repr: a function. with repr, you generally get a representation of the value as a legal Python expression (获得值的合法Python表达式表示)

长字符串、原始字符串和字节 (Long Strings, Raw Strings and Bytes)

write string that include newlines(long strings) or backslash(raw strings)。

Python2: there is a separate syntax for writing string with special symbols of different kinds, producing objects of the unicode type.

Python3: all strings are unicode strings. a new syntax has been introduced to specify a bytes object.

1. Long Strings (长字符串)

tuple quotes, tuple double quotes (三引号)。

2. Raw Strings (原始字符串)

写正则表达式时很有用 (don’t treat \ as a special character)。

raw string are prefixed with r, e.g. r'C:\Program Files\aaa'

The last character in raw string cannot be a backslash,e.g. str1 = r'C:\' 的写法将报错 SyntaxError: EOL while scanning string literal

如果一定要最后一个字符是 \,可以用 String Concatenate 的写法 str2 = r'C:' '\\'

3. Unicode, Bytes, and Bytearray

Python 字符串使用 Unicode 编码来表示文本。

每个 Unicode 字符都用一个码点(code point)表示,而码点是 Unicode 标准给每个字符指定的数字。

指定 Unicode 字符的通用机制:使用 16 或 32 位的十六进制字面量(分别加上前缀\u\U)或者使用字符的 Unicode 名称(\N{name})。

字符的 Unicode 码点和名称,参考:https://unicode-table.com/cn/

在内存和磁盘中,所有对象都是以二进制数字(0和1)表示的(这些数字每8个为一组(chunks),即1字节(bytes)),字符串也不例外。

在 C 语言中,这些字节完全暴露,字符串就是字节序列。Python 如果要与 C 语言交互,或者将文本写入文件或通过网络套接字发送出去,Python 提供了两种类似的类型:不可变的 bytes (immutable bytes) 和可变的 bytearray (mutable bytearray)。

1 字节只能表示 256 个不同的值,离 Unicode 标准的要求差很远。Python bytes 字面量只支持 ASCII 标准中的 128 个字符,而余下的 128 个值必须用转义序列表示,如 \xf0 表示十六进制值 0xf0(即240)。

ASCII 和 Unicode 定义的都是非负整数和字符之间的映射,但存在细微的差别:Unicode 码点是使用整数定义的,而 ASCII 字符是使用对应的数及其二进制编码定义的

超过 1 字节后,直接将每个码点表示为相应的二进制数可能不再可行。主要问题在于字节顺序以及浪费空间

如果对于每个码点都使用相同数量的字节进行编码,就必须考虑到文本可能包含生僻字母。有一种 Unicode 编码标准是基于这种考虑的,它就是 UTF-32。

但 UTF-32 很费空间:

1
2
3
"Hello, World!".encode("ASCII")   
"Hello, World!".encode("UTF-8")
"Hello, World!".encode("UTF-32")

an alternate(variable encoding): ASCII encoding is still used for single-byte encoding, retaining compatibility with older systems. characters outside this range use multiple bytes(up to six)

The difference between ASCII and UTF-8 appears once we use some slightly more exotic characters,此时.encode(“ASCII”)会出现类似如下错误

UnicodeEncode Error: ‘ascii’ codec can’t encode character ‘\xe6’ in position 1: ordinal not in range(128)

supply another argument to encode, telling it what to do with errors.(默认是’strict’)

例如:

1
2
3
4
"...".encode("ASCII", "ignore")
"...".encode("ASCII", "replace")
"...".encode("ASCII", "backslashreplace")
"...".encode("ASCII", "xmlcharrefreplace")

“…”.encode()的默认是UTF-8
bytes可以decode为strings

1
b"...".decode()

The bytes object it self doesn’t know about encoding

rather than using encode and decode, you might want to construct the bytes and str objects

例如:

1
2
bytes("...", encoding="utf-8")
str(b'...', encoding="utf-8")

更多参考:https://docs.python.org/3/howto/unicode.html

batearray, a mutable version of bytes, it’s like a string where you can modify the characters

to replace a character, you have to assign an int in range 0…255 to it. So if you want to actually insert a character, you have to get its ordinal value, using ord

2. Lists and Tuples

Zero Index

the zero indexing convention has a natural interpretation of an offset from the beginning of the sequence, with negative indexes wrapping around to the end.

List vs. Tuple

  • The main difference between lists and tuples is that you can change a list, but you can’t change a tuple.
  • tuples can be used as dictionary keys. There lists aren’t allowed, because you aren’t allowed to modify keys.

container

python has a basic notion of a kind of data structure called a container, which is basically any object that can contain other objects. the two main kinds of containers are sequences (such as lists and tuples) and mappings (such as dictionaries). While the elements of a sequence are numbered, each element in a mapping has a name (also called a key).

Common Sequence Operations

  • indexing, slicing, adding, multiplying, and checking for membership.
  • One important operation not covered here is iteration — Chap5

Slicing shortcut

if the slice continues to the end of the sequence, you may simply leave out the last index.

1
2
3
4
number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
number[-3:] # 的结果是 [8, 9, 10]
number[-3: 0] # 的结果是 [], any time the leftmost index in a slice comes later in the sequence than the second one, the result is always an empty sequence.
number[-3: -1] # 的结果是 [8, 9]

the step size can’t be zero—that wouldn’t get you anywhere—but it can be negative, which means extracting the elements from right to left.

1
numbers[8:3:-1] # 的结果是 [9, 8, 7, 6, 5]

Sequences can be concatenated with the addition (plus) operator.
In general, you cannot concatenate sequences of different types.(例如,只能list to list, str to str)

Multiplying a sequence by a number x creates a new sequence

None, Empty Lists, ans Initialization

An empty list is simply written as two brackets ([])—there’s nothing in it.
None is a Python value and means exactly that—“nothing here.”
So if you want to initialize a list of length 10, you could do the following:
sequence = [None] * 10

To check whether a value can be found in a sequence, you use the in operator. (boolean operator)
in general, the in operator checks whether an object is a member of a sequence (or some other collection).
nowadays, you can use the in operator to check whether any string is a substring of another.

The built-in functions len, min, and max can be quite useful.
len returns the number of elements a sequence contains.
min and max return the smallest and largest elements of the sequence, respectively.

Lists: Python’s Workhorse

create a list from a string.

1
list('Hello') # 结果 ['H', 'e', 'l', 'l', 'o']

list works with all kinds of sequences, not just strings. (这里的list是类不是函数)
逆运算:
1
''.join( ['H', 'e', 'l', 'l', 'o']) # 的结果 "Hello"

some of the ways you can change a list: item assignments, item deletion, slice assignments, and list methods.
Deleting elements from a list simply use the del statement.

Assigning to Slices: assign to several positions at once.

1
2
name = list('Perl')
name[2:] = list('ar') # 的结果是 ['P', 'e', 'a', 'r']

you may also replace the slice with a sequence whose length is different from that of the original.

1
name[1:] = list('ython') # 的结果是 ['P', 'y', 't', 'h', 'o', 'n']

Slice assignments can even be used to insert elements without replacing any of the original ones.

1
name[2:2] = ['a'] # 的结果是 ['p', 'e', 'a', 'r', 'l']

You can do the reverse to delete a slice.

1
name[1:3] = [] # 的结果是 ['p', 'l']

List method

  • append: append an object to the end of a list. append, like several similar methods, changes the list in place.
  • clear: clears the contents of a list, in place.
  • copy: copies a list. Recall that a normal assignment simply binds another name to the same list.
1
2
3
4
5
a = [1, 2, 3]
b = a
b[1] = 4 # 的结果是 a = [1, 4, 3]
c = a.copy()
c[1] = 4 # 的结果是 a = [1, 2, 3]

It’s similar to using a[:] or list(a), both of which will also copy a.

  • count: counts the occurrences of an element in a list.
  • extend: The extend method allows you to append several values at once by supplying a sequence of the values you want to append. This may seem similar to concatenation, but the important difference is that the extended sequence is modified. This is not the case in ordinary concatenation(list1 + list2), in which a completely new sequence is returned.
    The effect of extend can be achieved by assigning to slices, as follows:

    1
    2
    3
    a = [1, 2, 3]
    b = [4, 5, 6]
    a[len(a):] = b # 的结果是 a = [1, 2, 3, 4, 5, 6] (不推荐的写法)
  • index: searching lists to find the index of the first occurrence of a value. if not found, get an exception.

  • insert: insert an object into a list.
  • pop: removes an element (by default, the last one) from the list and returns it. the pop method is the only list method that both modifies the list and returns a value (other than None).
  • remove: remove the first occurrence of a value. you cannot remove something if it isn’t in the list to begin with. “nonreturning in-place changing” methods. It modifies the list but returns nothing (as opposed to pop).
  • reverse: reverses the elements in the list. changes the list and does not return anything (just like remove and sort)
    if you want to iterate over a sequence in reverse, you can use the reversed function. this function doesn’t return a list, though; it returns an iterator. You can convert the returned object with list. list(reversed(x))
  • sort: sort lists in place. from Python 2.3 on, the sort method uses a stable sorting algorithm.
    Another way of getting a sorted copy of a list is using the sorted function. This function can actually be used on any sequence but will always return a list.

advanced sorting

The sort method takes two optional arguments: key and reverse. If you want to use them, you normally specify them by name(keyword arguments)

1
2
3
x = ['aardvark', 'abalone', 'acme', 'add', 'aerate']
x.sort(key=len) # 结果为 ['add', 'acme', 'aerate', 'abalone', 'aardvark']
x.sort(reverse=True)

The key and reverse arguments are available in the sorted function as well. In many cases, using a custom functions for key will be useful.(chap6)

Tuples: Immutable Sequence

if you separate some values with commas, you automatically have a tuple.
产生长度为1的tuple的时候,逗号很重要
(0) 是 int
(0,) 是 tuple

The tuple function works in pretty much the same way as list: it takes one sequence argument and converts it to a tuple.

Tuple 相比list的好处:
They can be used as keys in mappings
They are returned by some built-in functions and methods

3. Working with String

Basic String Operations

All the standard sequence operations (indexing, slicing, multiplication, membership, length, minimum, and maximum) work with strings, as you saw in the previous chapter.
strings are immutable, so all kinds of item or slice assignments are illegal.

String Formatting: The Short Version

Formatting values as strings is such an important operation, and one that has to cater to such a diverse set of requirements, that several approaches have been added to the language over the years.

Historically, the main solution was to use the (aptly named) string formatting operator, the percent sign. The behavior of this operator emulates the classic printf function from the C language.

1
2
3
format = "Hello, %s. %s enough for ya?"
values = ('world', 'Hot')
format % values

The %s parts of the format string are called conversion specifiers.

Another solution you may encounter is so-called template strings, which appeared a while back as an attempt to simplify the basic formatting mechanism, using a syntax similar to UNIX shells

1
2
3
from string import Template
tmpl = Template("Hello, $who! $what enough for ya?")
tmpl.substitute(who="Mars", what="Dusty")

When writing new code, the mechanism of choice is the format string method, which combines and extends the strong points of the earlier methods.
The simplest case is where the fields have no name, or where each name is just an index.

1
"{3} {0} {2} {1} {3} {0}".format("be", "not", "or", "to")

Named fields

1
2
3
from math import pi

"{name} is approximately {value:.2f}.".format(value=pi, name="pi")

String Formatting: The Long Version

The most exciting part of a format string is found in the guts of the replacement fields, consisting of the following parts, all of which are optional:

  • A field name. An index or identifier. This tells us which value will be formatted and spliced into this specific field. In addition to naming the object itself, we may also name a specific part of the value, such as an element of a list, for example.
  • A conversion flag. An exclamation mark(感叹号), followed by a single character. The currently supported ones are r (for repr), s (for str), or a (for ascii). If supplied, this flag overrides the object’s own formatting mechanisms and uses the specified function to turn it into a string before any further formatting.
  • A format specifier. A colon, followed by an expression in the format specification mini-language. This lets us specify details of the final formatting, including the type of formatting (for example, string, floating-point or hexadecimal number), the width of the field and the precision of numbers, how to display signs and thousands separators, and various forms of alignment and padding.

Replacement Field Names

The indices of the unnamed arguments may also be used to request them out of order.

1
"{foo} {1} {bar} {0}".format(1, 2, bar=4, foo=3)

you don’t have to use the provided values themselves—you can access parts of them, just as in ordinary Python code.
As you can see, we can use both indexing and the dot notation for methods, attributes or variables, and functions in imported modules.

1
2
3
4
5
6
7
fullname = ["Alfred", "Smoketoomuch"]
"Mr {name[1]}".format(name=fullname)

import math

tmpl = "The {mod.__name__}" module defines the value {mod.pi} for pi
tmpl.format(mod=math)

Basic Conversions

Once you’ve specified what a field should contain, you can add instructions on how to format it.

First, you can supply a conversion flag.

1
print("{pi!s} {pi!r} {pi!a}".format(pi="pi"))

The three flags (s, r, and a) result in conversion using str, repr, and ascii, respectively.

The str function generally creates a natural-looking string version of the value (in this case, it does nothing to the input string);
the repr string tries to create a Python representation of the given value (in this case, a string literal),
while the ascii function insists on creating a representation that contains only character permitted in the ASCII encoding. This is similar to how repr worked in Python 2.

You can also specify the type of value you are converting—or, rather, what kind of value you’d like it to be treated as. For example, you may supply an integer but want to treat it as a decimal number. You do this by using the f character (for fixed point) in the format specification, that is, after the colon separator.

1
2
"The number is {num:f}".format(num=42) # 浮点
"The number is {num:b}".format(num=42) # 二进制

Width, Precision, and Thousands Separators

1
2
3
4
5
"{num:10}".format(num=3)
"{name:10}".format(name="Bob")
"Pi day is {pi:.2f}".format(pi=math.pi)
"{pi:10.2f}".format(pi=math.pi)
"{:.5}".format("Guido van Rossum")

you can indicate that you want thousands separators, by using a comma.

1
"One googol is {:,}".format(10 ** 100)

Signs, Alignment, and Zero-Padding

A zero means that the number will be zero-padded.

1
{:010.2f}.format(pi)

You specify left, right and centered alignment with <, >, and ^, respectively.

1
print("{0:<10.2f}\n{0:^10.2f}\n{0:>10.2f}".format(pi))

You can augment the alignment specifier with a fill character, which is used instead of the space character.

1
"{:$^15}".format(" WIN BIG ")

There’s also the more specialized specifier =, which places any fill characters between sign and digits.

1
2
print("{0:10.2f}\n{1:10.2f}".format(pi, -pi))
print("{0:10.2f}\n{1:=10.2f}".format(pi, -pi))

If you want to include signs for positive numbers as well, you use the specifier + (after the alignment specifier, if any), instead of the default -. If you use space character, positive will have a space inserted instead of a +.

1
2
3
print("{0:-.2}\n{1:-.2}".format(pi, -pi)) # default
print("{0:+.2}\n{1:+.2}".format(pi, -pi))
print("{0: .2}\n{1: .2}".format(pi, -pi))

One final component is the hash (#) option, which you place between the sign and width (if they are present). This triggers an alternate form of conversion, with the details differing between types.
for binary, octal, and hexadecimal conversion, a prefix is added.
For various types of decimal numbers, it forces the inclusion of the decimal point (and for g, it keeps decimal zeros).

1
2
3
4
"{:b}".format(42)
"{:#b}".format(42)
"{:g}".format(42)
"{:#g}".format(42)

String Methods

only some of the most useful ones are described here. For a full reference, see Appendix B.

even though string methods have completely upstaged the string module, the module still includes a few constants and functions that aren’t available as string methods.

string 模块的一些常量

  • string.digits: A string containing the digits 0–9
  • string.ascii_letters: A string containing all aSCii letters (uppercase and lowercase)
  • string.ascii_lowercase: A string containing all lowercase aSCii letters
  • string.printable: A string containing all printable aSCii characters
  • string.punctuation: A string containing all aSCii punctuation characters
  • string.ascii_uppercase: A string containing all uppercase aSCii letters

字符串对象的方法

  • center

centers the string by padding it on either side with a given fill character—spaces by default.

1
"The Middle by Jimmy Eat World".center(39, "*")

In Appendix B: ljust, rjust, zfill.

  • find

finds a substring within a larger string. It returns the leftmost index where the substring is found. If it is not found, –1 is returned.
You may also supply a starting point for your search and, optionally, an ending point.

参考附录B: rfind, index, rindex, count, startswith, endswith.

  • join

the inverse of split

1
2
dirs = "", "usr", "bin", "env"
print("C:" + "\\".join(dirs))
  • lower

return a lowercase version of string

相关的方法 islower, istitle, isupper, translate
参考附录B: capitalize, casefold, swapcase, title, upper

  • title

所有词的首字母大写,其它字母小写。但单词的边界需要注意。string 模块有一个函数 capwords 也有类似功能,单词边界的认定与 title 方法有所不同。

1
2
"that's all folks".title() # 结果为 "That'S All Folks"
string.capwords("that's all folks") # 结果为 "That's All Folks"
  • replace

all the occurrences of one string have been replaced by another.
参考附录B: expandtabs

  • split

Note that if no separator is supplied, the default is to split on all runs of consecutive whitespace characters(spaces, tabs, newlines, and so on).
相关的方法: join.
参考附录B: partition, rpartition, rsplit, splitlines.

  • strip

returns a string where whitespace on the left and right (but not internally) has been stripped (removed)
You can also specify which characters are to be stripped, by listing them all in a string parameter.

1
'*** SPAM * for * everyone!!! ***'.strip(' *!')

参考附录B: lstrip, rstrip

  • translate

unlike replace, translate works only with single characters

example: Let’s say you want to translate a plain English text into one with a German accent. To do this, you must replace the character c with k, and s with z.

Before you can use translate, however, you must make a translation table. This translation table contains information about which Unicode code points should be translated to which. You construct such a table using the maketrans method on the string type str itself.

1
table = str.maketrans('cs', 'kz')

table is a mapping between Unicode code points.

Once you have a translation table, you can use it as an argument to the translate method.

1
'this is an incredible test'.translate(table)

An optional third argument can be supplied to maketrans, specifying letters that should be deleted.

1
table = str.maketrans('cs', 'kz', ' ')

4. Dictionary: When Indices Won’t Do

a data structure in which you can refer to each value by name. This type of structure is called a mapping. The only built-in mapping type in Python is the dictionary.

The values in a dictionary don’t have any particular order but are stored under a key, which may be a number, a string, or even a tuple.

Dictionary Uses

适合字典的一些场景:

  • Representing the state of a game board, with each key being a tuple of coordinates
  • Storing file modification times, with file names as keys
  • A digital telephone/address book

Creating and Using Dictionaries

The dict function

construct dictionaries from other mappings (for example, other dictionaries) or from sequences of (key, value) pairs.

Basic Dictionary Operations

The basic behavior of a dictionary in many ways mirrors that of a sequence.

  • len(d) returns the number of items (key-value pairs) in d.
  • d[k] returns the value associated with the key k.
  • d[k] = v associates the value v with the key k.
  • del d[k] deletes the item with key k.
  • k in d checks whether there is an item in d that has the key k.

与 sequence 的区别

  • Key types: Dictionary keys don’t have to be integers (though they may be). They may be any immutable type, such as floating-point (real) numbers, strings, or tuples.
  • Automatic addition: You can assign a value to a key, even if that key isn’t in the dictionary to begin with; in that case, a new item will be created. You cannot assign a value to an index outside the list’s range
  • Membership: The expression k in d (where d is a dictionary) looks for a key, not a value. The expression v in l, on the other hand (where l is a list) looks for a value, not an index.

String Formatting with Dictionaries

the dictionary may contain all kinds of information, and your format string will only pick out whatever it needs. You’ll have to specify that you’re supplying a mapping, by using format_map.

1
2
3
4
5
6
7
8
9
template = """<html>
<head><title>{title}</title></head>
<body>
<h1>{title}</h>
<p>{text}</p>
</body>
"""
data = {"title": "My Home Page", "text": "Welcome to my home page!"}
print(template.format_map(data))

Dictionary Methods

  • clear

removes all items from the dictionary. This is an in-place operation (like list.sort), so it returns nothing

  • copy

The copy method returns a new dictionary with the same key-value pairs (a shallow copy, since the values themselves are the same, not copies).

1
2
3
4
5
6
x = {"username": "admin", "machines": ["foo", "bar", "baz"]}
y = x.copy()
y["username"] = "mlh"
y["machines"].remove("bar")
# x: {"username": "admin", "machines": ["foo", "baz"]}
# y: {"username": "mlh", "machines": ["foo", "baz"]}

As you can see, when you replace a value in the copy, the original is unaffected. However, if you modify a value (in place, without replacing it), the original is changed as well because the same value is stored there (like the ‘machines’ list in this example).

One way to avoid that problem is to make a deepcopy

  • fromkeys

creates a new dictionary with the given keys, each with a default corresponding value of None.

This example first constructs an empty dictionary and then calls the fromkeys method on that in order to create another dictionary—a somewhat redundant strategy.

1
2
{}.fromkeys(['name', 'age']) 
{'age': None, 'name': None}
  • get
    a forgiving way of accessing dictionary items.
    Ordinarily, when you try to access an item that is not present in the dictionary, things go very wrong.

when you use get to access a nonexistent key, there is no exception. Instead, you get the value None. You may supply your own “default” value, which is then used instead of None.

  • items
    returns all the items of the dictionary as a list of items in which each item is of the form (key, value). The items are not returned in any particular order.

The return value is of a special type called a dictionary view.
Dictionary views can be used for iteration, In addition, you can determine their length and check for membership.

  • keys

returns a dictionary view of the keys in the dictionary.

  • pop

ponding to a given key and then to remove the key-value pair from the dictionary.

  • popitem

similar to list.pop, which pops off the last element of a list. Unlike list.pop, however, popitem pops off an arbitrary item because dictionaries don’t have a “last element” or any order
This may be very useful if you want to remove and process the items one by one in an efficient way (without retrieving a list of the keys first).

if you want the popitem method to follow a predictable ordering, take a look at the OrderedDict class from the collections module.

  • setdefault

similar to get, in that it retrieves a value associated with a given key. In addition to the get functionality, setdefault sets the value corresponding to the given key if it is not already in the dictionary.
As you can see, when the key is missing, setdefault returns the default and updates the dictionary accordingly. If the key is present, its value is returned, and the dictionary is left unchanged.
The default is optional, as with get; if it is left out, None is used.

1
2
for girl in girls:
letterGirls.setdefault(girl[0], []).append(girl)

if you want a global default for the entire dictionary, check out the defaultdict class from the collections module.

  • update

updates one dictionary with the items of another.

1
d.update(x)

The items in the supplied dictionary are added to the old one, supplanting any items there with the same keys.

The update method can be called in the same way as the dict function — This means that update can be called with a mapping, a sequence (or other iterable object) of (key, value) pairs, or keyword arguments.

  • values

returns a dictionary view of the values in the dictionary. Unlike keys, the view returned by values may contain duplicates.

5. Conditionals, Loops, Some Other Srtatements

More About print and import

For many applications, logging (using the logging module) will be more appropriate than using print.

Assignment Magic

Sequence Unpacking

You can perform several different assignments simultaneously.

1
a, b = b, a

Instead of ensuring that the number of values matches exactly, you can gather up any superfluous ones using the star operator (*).
the starred variable will always end up containing a list. This is true even if the number of values matches exactly.

Chained Assignments

1
x = y = somefunction()

is the same as

1
2
y = somefunction() 
x = y

Note that the preceding statements may not be the same as
1
2
x = somefunction() 
y = somefunction()

Augmented Assignments

1
+=, *=, -=, /=, %=

Blocks: The Joy of Indentation

A block is a group of statements that can be executed if a condition is true (conditional statements), executed several times (loops), and so on. A block is created by indenting a part of your code

Conditions and Conditional Statements

The following values are considered by the interpreter to mean false when evaluated as a Boolean expression

1
False None 0 "" () [] {}

Because any value can be used as a Boolean value, you will most likely rarely (if ever) need such an explicit conversion (that is, Python will automatically convert the values for you).

although [] and "" are both false (that is, bool([]) == bool("") == False), they are not equal (that is, [] != ""). the same goes for other false objects of different types (for example, the possibly more obvious example () != False).

close relative of the if statement, called the conditional expression. This is Python’s version of the ternary operator from C.

1
status = "friend" if name.endswith("Gumby") else "stranger"

Comparison Operators

Expression Description
x == y x equals y
x < y x is less than y
x > y x is greater than y
x >= y x is greater than or equal to y
x <= y x is less than or equal to y
x != y x is not equal to y
x is y x and y are the same object
x is not y x and y are difference object
x in y x is a member of the container(e.g., sequence) y
x not in y x is not a member of the container(e.g., sequence) y

a < b, a <= b, such a comparison makes sense only if x and y are of the same or closely related types (such as two integers or an integer and a floating-point number).

== 和 is 的区别

1
2
3
4
5
x = y = [1, 2, 3]
z = [1, 2, 3]
x == z # 结果为 True
x is y # 结果为 True
x is z # 结果为 False

Until the last example, this looks fine, but then you get that strange result: x is not z, even though they are equal. Why? Because is tests for identity, rather than equality. The variables x and y have been bound to the same list, while z is simply bound to another list that happens to contain the same values in the same order. They may be equal, but they aren’t the same object.

avoid the use of is with basic, immutable values such as numbers and strings. the result is unpredictable because of the way python handles these objects internally.

Strings are compared according to their order when sorted alphabetically.

The ordering is alphabetical, but the alphabet is all of Unicode, ordered by their code points.

Actually, characters are sorted by their ordinal values. The ordinal value of a letter can be found with the ord function, whose inverse is chr:

Other sequences are compared in the same manner, except that instead of characters, you may have other types of elements.

1
[1, 2] < [2, 1] # 结果为 True

If the sequences contain other sequences as elements, the same rule applies to these sequence elements.

1
[2, [1, 4]] < [2, [1, 5]] # 结果为 True

SHORT-CIRCUIT LOGIC AND CONDITIONAL EXPRESSIONS

Assertions

5. Loops

Basically, an iterable object is any object that you can iterate over (that is, use in a for loop). You learn more about iterables and iterators in Chapter 9

built-in function: range

Iterating Over Dictionaries

1
2
3
4
5
for key in d:
print(key, 'corresponds to', d[key])

for key, value in d.items():
print(key, 'corresponds to', value)

If the order is important, you can store the keys or values in a separate list

If you want your mapping to remember the insertion order of its items, you can use class OrderedDict from the collections module.

Some Iteration Utilities

Python has several functions that can be useful when iterating over a sequence (or other iterable object). Some of these are available in the itertools module (mentioned in Chapter 10), but there are some built-in functions that come in quite handy as well.

Parallel Iteration

A useful tool for parallel iteration is the built-in function zip, returning a sequence of tuples. The return value is a special zip object, meant for iteration, but it can be converted using list, to take a look at its contents.
The zip function works with as many sequences as you want. It’s important to note what zip does when the sequences are of different lengths: it stops when the shortest sequence is used up.

Numbered Iteration

enumerate

Reversed and Sorted Iteration

reversed and sorted, work on any sequence or iterable object, and instead of modifying the object in place, they return reversed and sorted versions

Note that although sorted returns a list, reversed returns a more mysterious iterable object, just like zip. You don’t need to worry about what this really means; you can use it in for loops or methods such as join without any problems. You just can’t index or slice it, or call list methods on it directly. In order to perform those tasks, just convert the returned object with list.

We can use the trick of lowercasing to get proper alphabetical sorting. For example, you could use str.lower as the key argument to sort or sorted. For example, sorted("aBc", key=str.lower) returns [‘a’, ‘B’, ‘c’] .

Breaking Out of Loops

break
continue
while True/break idiom
else Clauses in Loops — else clause to your loop—it is executed only if you didn’t call break.

Comprehensions—Slightly Loopy

List comprehension is a way of making lists from other lists (similar to set comprehension, if you know that term from mathematics).

Using normal parentheses instead of brackets will not give you a “tuple comprehension”—you’ll end up with a generator.
use curly braces to perform dictionary comprehension.

And Three for the Road

pass — placeholder

del

1
2
3
4
5
scoundrel = {'age':42, 'first name': 'Robin', 'last name': 'of Locksley'}
robin = scoundrel
scoundrel = None
robin # 结果为 {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'}
robin = None

At first, robin and scoundrel are both bound to the same dictionary. So when I assign None to scoundrel, the dictionary is still available through robin. But when I assign None to robin as well, the dictionary suddenly floats around in the memory of the computer with no name attached to it. There is no way I can retrieve it or use it, so the Python interpreter (in its infinite wisdom) simply deletes it. (This is called garbage collection.) Note that I could have used any value other than None as well. The dictionary would be just as gone.

Another way of doing this is to use the del statement(which we used to delete sequence and dictionary elements)

1
2
3
4
5
6
x = ["Hello", "world"]
y = x
y[1] = "Python"
x # 结果为 ['Hello', 'Python']
del x
y # 结果为 ['Hello', 'Python']

x and y referred to the same list, but deleting x didn’t affect y at all. The reason for this is that you delete only the name, not the list itself (the value). In fact, there is no way to delete values in Python—and you don’t really need to, because the Python interpreter does it by itself whenever you don’t use the value anymore.

Executing and Evaluating Strings with exec and eval

execute Python code stored in a string. This is a potential security hole of great dimensions. If you execute a string where parts of the contents have been supplied by a user, you have little or no control over what code you are executing. This is especially dangerous in network applications, such as Common Gateway Interface (CGI) scripts

  • exec
1
exec("print('Hello, world!')") # 结果为 Hello, world!

In most cases, you want to supply it with a namespace—a place where it can put its variables. Otherwise, the code will corrupt your namespace (that is, change your variables).

1
2
3
from math import sqrt
exec("sqrt = 1")
sqrt(4) # 报错

报错信息

1
2
3
4
Traceback (most recent call last):
File "<pyshell#18>", line 1, in ?
sqrt(4)
TypeError: object is not callable: 1

The exec function is mainly useful when you build the code string on the fly. And if the string is built from parts that you get from other places, and possibly from the user, you can rarely be certain of exactly what it will contain. So to be safe, you give it a dictionary, which will work as a namespace for it

1
2
3
4
5
from math import sqrt
scope = {}
exec("sqrt = 1", scope)
sqrt(4) # 结果为 2.0
scope["sqrt"] # 结果为 1

Note that if you try to print out scope, you see that it contains a lot of stuff because the dictionary called __builtins__ is automatically added and contains all built-in functions and values.

1
2
len(scope) # 结果为 2
scope.keys() # 结果为 ["sqrt", "__builtins__"]
  • eval

eval evaluates a Python expression (written in a string) and returns the resulting value. (exec doesn’t return anything because it is a statement itself.)

exec 和 eval 的安全问题


Share