NATIVE DATATYPES
原生类型(就是PTN本身支持的类型)
多做事,少说话
--kuramantboy
34.57
DIVING IN
Cast aside your first Python program for just a minute, and let’s talk about datatypes. In Python, every value has a datatype, but you don’t need to declare the datatype of variables. How does that work? Based on each variable’s original assignment, Python figures out what type it is and keeps tracks of that internally.
本章讨论Ptn的数据类型,Ptn中只要是值就会对应一个类型。声明变量时,不需要提供数据类型。这貌似有点不可思议,其实工作原理很简单,就是在给变量赋值的时候,Ptn会自动确定它的类型,并在内部记录并跟踪。
Python has many native datatypes. Here are the important ones:
Ptn有很多(很多是多少?)原生类型,下面列举一些:
1. Booleans are either True or False.
Booleans类型取值True或False。
2. Numbers can be integers (1 and 2), floats (1.1 and 1.2), fractions (1/2 and 2/3), or even complex numbers.
Numbers类型取值可以是整数(如1或2),浮点数(如1.1或2.2),分数(如1/2或2/3),甚至还包括复数complex numbers。
3. Strings are sequences of Unicode characters, e.g. an HTML document.
字符串类型是一串Unicode字符,例如,HTML文档。
4. Bytes and byte arrays, e.g. a JPEG image file.
Bytes类型,byte数组类型,例如,JPEG图像文件。
5. Lists are ordered sequences of values.
列表类型是按键入顺序排列的一组值。
6. Tuples are ordered, immutable sequences of values.
元组类型是按键入顺序排列的一组值,且定义后不可改变
7. Sets are unordered bags of values.
集合类型是不按键入顺序排列的很多堆的值(不理解的话,后面会给你解释)
8. Dictionaries are unordered bags of key-value pairs.
字典类型是不按键入顺序排列的很多堆键值对(不理解的话,后面会给你解释)。
Of course, there are more types than these. Everything is an object in Python, so there are types like module, function, class, method, file, and even compiled code. You’ve already seen some of these:
当然,还有更多的原生类型。Ptn中一切都是对象,例如模块、函数、类、方法、文件,甚至编译后的代码:
modules have names, functions have docstrings, &c. You’ll learn about classes in Classes & Iterators, and about files in Files.
模块有名字,函数有docstrings。类在Classes & Iterators中讨论,文件在Files中讨论。
Strings and bytes are important enough — and complicated enough — that they get their own chapter. Let’s look at the others first.
Strings 和 bytes有些复杂,会在单独的章节中讲。
BOOLEANS(布尔值)
You can use virtually any expression in a boolean context.
Booleans are either true or false. Python has two constants, cleverly named True and False, which can be used to assign boolean values directly. Expressions can also evaluate to a boolean value. In certain places (like if statements), Python expects an expression to evaluate to a boolean value. These places are called boolean contexts. You can use virtually any expression in a boolean context, and Python will try to determine its truth value. Different datatypes have different rules about which values are true or false in a boolean context. (This will make more sense once you see some concrete examples later in this chapter.)
Booleans只有两种状态,真或假。Ptn中有两个常量,名字是True和False,可以直接用来赋值。表达式也可以转换为布尔值。在某些地方,比如说if语句中,Ptn会将表达式转换为布尔值,我们称这类地方为布尔上下文,布尔上下文中可以出现任何表达式。不同的数据类型在布尔上下文中的布尔值要根据该类型的具体规则来看。看完下面的例子,会加深我们的认识。
For example, take this snippet from humansize.py:
例如下面的humansize.py:
if size < 0:
raise ValueError('number must be non-negative')
size is an integer, 0 is an integer, and < is a numerical operator. The result of the expression size < 0 is always a boolean. You can test this yourself in the Python interactive shell:
size < 0表达式的结果始终为真,可以将下面的内容实践一下:
>>> size = 1
>>> size < 0
False
>>> size = 0
>>> size < 0
False
>>> size = -1
>>> size < 0
True
Due to some legacy issues left over from Python 2, booleans can be treated as numbers. True is 1; False is 0.
因为Pt2的历史遗留问题,也可以将布尔值看作数字,True是1,False是0。下面是示例:
>>> True + True
2
>>> True - False
1
>>> True * False
0
>>> True / False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: int division or modulo by zero
Ew, ew, ew! Don’t do that. Forget I even mentioned it.
最好不要像上面一样编写代码,这会让人看不明白,真+真=2是什么意思呢。
NUMBERS数字类型
Numbers are awesome. There are so many to choose from. Python supports both integers and floating point numbers. There’s no type declaration to distinguish them; Python tells them apart by the presence or absence of a decimal point.
数字类型包含的种类比较多。Ptn支持整数和浮点数,因为不用声明类型,所以根据小数点是否存在来判断。
>>> type(1) ①
<class 'int'>
>>> isinstance(1, int) ②
True
>>> 1 + 1 ③
2
>>> 1 + 1.0 ④
2.0
>>> type(2.0)
<class 'float'>
1. You can use the type() function to check the type of any value or variable. As you might expect, 1 is an int.
可以使用type()函数判断任何值或变量的类型,1是int类型
2. Similarly, you can use the isinstance() function to check whether a value or variable is of a given type.
可以使用isinstance()判断某个值或变量是否属于指定类型。
3. Adding an int to an int yields an int.
2个int类型的相加,值仍为Int类型。这就是废话
4. Adding an int to a float yields a float. Python coerces the int into a float to perform the addition, then returns a float as the result.
Int类型的值加float类型的值,结果为float类型。Ptn强制将int转换为float,结果也同样为float类型。
COERCING INTEGERS TO FLOATS AND VICE-VERSA
整型和浮点型间的强制转换
As you just saw, some operators (like addition) will coerce integers to floating point numbers as needed. You can also coerce them by yourself.
不仅加法等操作符可以引发强制转换,程序员也可以自己强制转换。
>>> float(2) ①
2.0
>>> int(2.0) ②
2
>>> int(2.5) ③
2
>>> int(-2.5) ④
-2
>>> 1.12345678901234567890 ⑤
1.1234567890123457
>>> type(1000000000000000) ⑥
<class 'int'>
1. You can explicitly coerce an int to a float by calling the float() function.
使用float()函数可以将int强制转换为float
2. Unsurprisingly, you can also coerce a float to an int by calling int().
也可以使用int()将float强制转换为int.
3. The int() function will truncate, not round.
int()会截断,不会四舍五入,即int(3.6) = 3而不是4
4. The int() function truncates negative numbers towards 0. It’s a true truncate function, not a floor function.
对于负数,int()函数是向0截取的。例如,int(-3.6) = -3 ,这要区别于取整函数(floor function)。
5. Floating point numbers are accurate to 15 decimal places.
浮点数精度为小数点后15位。
6. Integers can be arbitrarily large.
整数可以任意大,really?。请看
>>> a = 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
>>> a+1
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112L
☞Python 2 had separate types for int and long. The int datatype was limited by sys.maxint, which varied by platform but was usually 232-1. Python 3 has just one integer type, which behaves mostly like the old long type from Python 2. See PEP 237 for details.
Pt2过去有int和long两种类型。Int最大值为sys.maxint,该值根据系统平台不同而不同,一般取值为232-1。Pt3只有一种整型,与Pt2中的long型。详细信息,请参阅PEP 237。
COMMON NUMERICAL OPERATIONS
常见的数字操作符
You can do all kinds of things with numbers.
>>> 11 / 2 ①
5.5
>>> 11 // 2 ②
5
>>> −11 // 2 ③
−6
>>> 11.0 // 2 ④
5.0
>>> 11 ** 2 ⑤
121
>>> 11 % 2 ⑥
1
1. The / operator performs floating point division. It returns a float even if both the numerator and denominator are ints.
操作符 / 执行的是浮点除法。即使分子和分母都是整型,结果也是浮点型。
2. The // operator performs a quirky kind of integer division. When the result is positive, you can think of it as truncating (not rounding) to 0 decimal places, but be careful with that.
操作符 // 有点奇怪。当结果是正的,可以看作截取(但不四舍五入)小数点后的内容。使用的时候要小心。你可以自己试试它。
译者注:首先要说的是python中的除法运算,在python 2.5版本中存在两种除法运算,即所谓的true除法和floor除法。当使用x/y形式进行除法运算时,如果x和y都是整形,那么运算的会对结果进行截取,取运算的整数部分,比如2/3的运算结果是0;如果x和y中有一个是浮点数,那么会进行所谓的true除法,比如2.0/3的结果是0.66666666666666663。另外一种除法是采用x//y的形式,那么这里采用的是所谓floor除法,即得到不大于结果的最大整数值,这个运算时与操作数无关的。比如2//3的结果是0,-2//3的结果是-1,-2.0//3的结果是-1.0。
在未来的python 3.0中,x/y将只执行true除法,而与操作数无关;x//y则执行floor除法。如果需要在2.5版本的python中进行这样的用法,则需要在代码前加入from __future__ import division的声明。如:
Python代码
1. from __future__ import division
2. a=2/3
3. When integer-dividing negative numbers, the // operator rounds “up” to the nearest integer. Mathematically speaking, it’s rounding “down” since −6 is less than −5, but it could trip you up if you expecting it to truncate to −5.
当除法结果为负时,// 操作符得到不大于结果的最大整数值,这里是6,如果你认为是 5 那就错了
4. The // operator doesn’t always return an integer. If either the numerator or denominator is a float, it will still round to the nearest integer, but the actual return value will be a float.
// 操作符的结果并不总是整数。如果分子或分母是float型。结果会先
得到不大于结果的最大整数值,然后转换成float。
5. The ** operator means “raised to the power of.” 112 is 121.
**操作符是平方的操作。
6. The % operator gives the remainder after performing integer division. 11 divided by 2 is 5 with a remainder of 1, so the result here is 1.
% 操作符是取余数的操作。11除以2的余数是1。
☞In Python 2, the / operator usually meant integer division, but you could make it behave like floating point division by including a special directive in your code. In Python 3, the / operator always means floating point division. See PEP 238 for details.
在Ptn2中,/ 操作符通常表示整除,如果想要表示浮点整除,需要在代码中加入特别的指示(directive)。在Ptn3中,/ 操作符始终表示浮点整除,详细信息,请参阅PEP 238。
FRACTIONS
分数
Python isn’t limited to integers and floating point numbers. It can also do all the fancy math you learned in high school and promptly forgot about.
Ptn不限于整数和浮点数,还可以实现所有学习过的数学运算。
>>> import fractions ①
>>> x = fractions.Fraction(1, 3) ②
>>> x
Fraction(1, 3)
>>> x * 2 ③
Fraction(2, 3)
>>> fractions.Fraction(6, 4) ④
Fraction(3, 2)
>>> fractions.Fraction(0, 0) ⑤
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "fractions.py", line 96, in __new__
raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
ZeroDivisionError: Fraction(0, 0)
1. To start using fractions, import the fractions module.
导入fractions 模块。
2. To define a fraction, create a Fraction object and pass in the numerator and denominator.
若要定义分数,先创建一个Fraction对象,并传入分子和分母。
3. You can perform all the usual mathematical operations with fractions. Operations return a new Fraction object. 2 * (1/3) = (2/3)
我们可以对Fraction对象执行所有常用的数学运算。
4. The Fraction object will automatically reduce fractions. (6/4) = (3/2)
Fraction对象会自动约分。如,(6/4) = (3/2)
5. Python has the good sense not to create a fraction with a zero denominator.
Ptn在创建Fraction对象时,会严格检查分母是否为0
TRIGONOMETRY
三角函数
You can also do basic trigonometry in Python.
在Ptn中,还可以调用三角函数。
>>> import math
>>> math.pi ①
3.1415926535897931
>>> math.sin(math.pi / 2) ②
1.0
>>> math.tan(math.pi / 4) ③
0.99999999999999989
1. The math module has a constant for π, the ratio of a circle’s circumference to its diameter.
math.pi是常量——圆周率
2. The math module has all the basic trigonometric functions, including sin(), cos(), tan(), and variants like asin().
Math中还包括sin(), cos(), tan(),asin()等等。
3. Note, however, that Python does not have infinite precision. tan(π / 4) should return 1.0, not 0.99999999999999989.
Ptn不支持无限长精确浮点数,tan(π / 4)返回的是1.0而不是0.99999999999999989。
NUMBERS IN A BOOLEAN CONTEXT
布尔上下文中的数字
Zero values are false, and non-zero values are true.
0值是假,非0值为真。
You can use numbers in a boolean context, such as an if statement. Zero values are false, and non-zero values are true.
>>> def is_it_true(anything): ①
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true(1) ②
yes, it's true
>>> is_it_true(-1)
yes, it's true
>>> is_it_true(0)
no, it's false
>>> is_it_true(0.1) ③
yes, it's true
>>> is_it_true(0.0)
no, it's false
>>> import fractions
>>> is_it_true(fractions.Fraction(1, 2)) ④
yes, it's true
>>> is_it_true(fractions.Fraction(0, 1))
no, it's false
1. Did you know you can define your own functions in the Python interactive shell? Just press ENTER at the end of each line, and ENTER on a blank line to finish.
在Ptn交互shell下,连续按两次ENTER可以结束对函数的定义。
2. In a boolean context, non-zero integers are true; 0 is false.
在布尔上下文中,非0值是真,0值是假。
3. Non-zero floating point numbers are true; 0.0 is false. Be careful with this one! If there’s the slightest rounding error (not impossible, as you saw in the previous section) then Python will be testing 0.0000000000001 instead of 0 and will return True.
非0浮点数是真,0.0是假。这一点要注意。
4. Fractions can also be used in a boolean context. Fraction(0, n) is false for all values of n. All other fractions are true.
分手也可以用于布尔上下文。Fraction(0, n)是假,无论n为何值。其他分数则都为真。
LISTS
列表
Lists are Python’s workhorse datatype. When I say “list,” you might be thinking “array whose size I have to declare in advance, that can only contain items of the same type, &c.” Don’t think that. Lists are much cooler than that.
列表是Ptn中的重要数据类型。平常我们说列表的时候,你可能想这是一个提前声明大小的数组,并且其中只能存放相同的数据类型。在Ptn中,列表要比你前面所想的更加智能。
☞A list in Python is like an array in Perl 5. In Perl 5, variables that store arrays always start with the @ character; in Python, variables can be named anything, and Python keeps track of the datatype internally.
Ptn中的列表与Perl 5中的数组类似,在Perl 5中,数组变量始终以@字符打头。在Ptn中,变量名字没有任何限制,Ptn内部会自动跟踪该数据类型。
☞A list in Python is much more than an array in Java (although it can be used as one if that’s really all you want out of life). A better analogy would be to the ArrayList class, which can hold arbitrary objects and can expand dynamically as new items are added.
Ptn中的列表要优于Java中的数组,其实它更像ArrayList类,可以存放任意对象并动态扩展。
CREATING A LIST
创建列表
Creating a list is easy: use square brackets to wrap a comma-separated list of values.
很简单,在一对中括号内填入逗号分割的值。
>>> a_list = ['a', 'b', 'mpilgrim', 'z', 'example'] ①
>>> a_list
['a', 'b', 'mpilgrim', 'z', 'example']
>>> a_list[0] ②
'a'
>>> a_list[4] ③
'example'
>>> a_list[-1] ④
'example'
>>> a_list[-3] ⑤
'mpilgrim'
1. First, you define a list of five items. Note that they retain their original order. This is not an accident. A list is an ordered set of items.
首先,我们定义了一个含有5项内容的列表。注意,它们是按照键入的顺序排列的。
2. A list can be used like a zero-based array. The first item of any non-empty list is always a_list[0].
列表可以看作索引从0开始的数组。任何非空列表的第一项始终是a_list[0]。
3. The last item of this five-item list is a_list[4], because lists are always zero-based.
因为索引从0开始,所以最后一项是a_list[4]。
4. A negative index accesses items from the end of the list counting backwards. The last item of any non-empty list is always a_list[-1].
索引若为负数,则从列表倒数。任何非空列表的最后一项始终是a_list[-1]。
5. If the negative index is confusing to you, think of it this way: a_list[-n] == a_list[len(a_list) - n]. So in this list, a_list[-3] == a_list[5 - 3] == a_list[2].
如果负数索引,让你犯晕,你可以这样转换下。a_list[-n] == a_list[len(a_list) - n]。比如, a_list[-3] == a_list[5 - 3] == a_list[2].
SLICING A LIST
列表分片
a_list[0] is the first item of a_list.
a_list[0]是列表的第一项。
Once you’ve defined a list, you can get any part of it as a new list. This is called slicing the list.
定义一个列表后,就可以抽出其中任意一部分作为新列表。我们称之为列表分片。
>>> a_list
['a', 'b', 'mpilgrim', 'z', 'example']
>>> a_list[1:3] ①
['b', 'mpilgrim']
>>> a_list[1:-1] ②
['b', 'mpilgrim', 'z']
>>> a_list[0:3] ③
['a', 'b', 'mpilgrim']
>>> a_list[:3] ④
['a', 'b', 'mpilgrim']
>>> a_list[3:] ⑤
['z', 'example']
>>> a_list[:] ⑥
['a', 'b', 'mpilgrim', 'z', 'example']
1. You can get a part of a list, called a “slice”, by specifying two indices. The return value is a new list containing all the items of the list, in order, starting with the first slice index (in this case a_list[1]), up to but not including the second slice index (in this case a_list[3]).
通过指定索引就可以得到分片。从第一个索引开始到第二个索引结束(不包括第二个索引本身)。
2. Slicing works if one or both of the slice indices is negative. If it helps, you can think of it this way: reading the list from left to right, the first slice index specifies the first item you want, and the second slice index specifies the first item you don’t want. The return value is everything in between.
如果分片中的索引1个或全部都是负数。我们看下示例:
>>> a= [1,2,3,4,5]
>>> a[-1:-5]
[ ]
>>> a[-1:-2]
[ ]
>>> a[-5:-1]
[1, 2, 3, 4]
>>>
3. Lists are zero-based, so a_list[0:3] returns the first three items of the list, starting at a_list[0], up to but not including a_list[3].
列表索引是从0开始计算的,a_list[0:3]返回前三项,从a_list[0]开始,直到但不包括a_list[3]。
4. If the left slice index is 0, you can leave it out, and 0 is implied. So a_list[:3] is the same as a_list[0:3], because the starting 0 is implied.
如果第一个索引是0,可以不写。比如,a_list[:3]和 a_list[0:3]是一样的。
5. Similarly, if the right slice index is the length of the list, you can leave it out. So a_list[3:] is the same as a_list[3:5], because this list has five items. There is a pleasing symmetry here. In this five-item list, a_list[:3] returns the first 3 items, and a_list[3:] returns the last two items. In fact, a_list[:n] will always return the first n items, and a_list[n:] will return the rest, regardless of the length of the list.
类似,如果第二个索引是列表长度,那么也可以不写。例如,a_list[3:]和a_list[3:5]是一样的,因为列表里只有5项。这种表达方式在实际应用中实很方便的,a_list[:3]返回前3项,a_list[3:]返回剩余的项。抽象上讲,a_list[:n]返回前n项,a_list[n:]返回列表中的其余项。
6. If both slice indices are left out, all items of the list are included. But this is not the same as the original a_list variable. It is a new list that happens to have all the same items. a_list[:] is shorthand for making a complete copy of a list.
如果两个索引都没有,那么就包含列表的所有项,但这与a_list变量并不完全一样,只是碰巧有同样的项。a_list[:]是复制列表时候的一种简单表达方式。
ADDING ITEMS TO A LIST
向列表中添加项
There are four ways to add items to a list.
有4中方式可以添加项。
>>> a_list = ['a']
>>> a_list = a_list + [2.0, 3] ①
>>> a_list ②
['a', 2.0, 3]
>>> a_list.append(True) ③
>>> a_list
['a', 2.0, 3, True]
>>> a_list.extend(['four', 'Ω']) ④
>>> a_list
['a', 2.0, 3, True, 'four', 'Ω']
>>> a_list.insert(0, 'Ω') ⑤
>>> a_list
['Ω', 'a', 2.0, 3, True, 'four', 'Ω']
1. The + operator concatenates lists to create a new list. A list can contain any number of items; there is no size limit (other than available memory). However, if memory is a concern, you should be aware that list concatenation creates a second list in memory. In this case, that new list is immediately assigned to the existing variable a_list. So this line of code is really a two-step process — concatenation then assignment — which can (temporarily) consume a lot of memory when you’re dealing with large lists.
操作符+将多个列表连接,从而创建一个新的列表。列表可以包含任意多项,没有限制,除非你内存有限。如果你内存有限,你要知道连接列表时候会创建一个辅助的列表,然后分派给现存的变量a_list。所以连接列表实际上是两步,连接然后赋值,创建辅助列表时会暂时消耗一部分内存,对于很大的列表,会消耗更大的内存。
2. A list can contain items of any datatype, and the items in a single list don’t all need to be the same type. Here we have a list containing a string, a floating point number, and an integer.
列表可以包含各种数据类型的项,并不要求一个列表中必须包含相同的项。上面示例中的列表,就包含了字符串、浮点和整数。
3. The append() method adds a single item to the end of the list. (Now we have four different datatypes in the list!)
append()方法可以将单独一项添加的列表尾部。(现在我们的列表中有4种不同的类型)
4. Lists are implemented as classes. “Creating” a list is really instantiating a class. As such, a list has methods that operate on it. The extend() method takes one argument, a list, and appends each of the items of the argument to the original list.
列表是作为类实现的。创建列表实际上是实例化一个类。列表还有对其进行操作的方法。在上例中,extend()方法使用了一个参数,该参数为列表,结果是将该参数附加到原来的列表尾部。
5. The insert() method inserts a single item into a list. The first argument is the index of the first item in the list that will get bumped out of position. List items do not need to be unique; for example, there are now two separate items with the value 'Ω': the first item, a_list[0], and the last item, a_list[6].
insert()方法将一项插入到列表,第一个参数是所要插入的位置的索引。列表中的项不要求是唯一的。例如,上面的示例,就有两个一样的项--”Ω”, 分别是a_list[0]和a_list[6]。
☞a_list.insert(0, value) is like the unshift() function in Perl. It adds an item to the beginning of the list, and all the other items have their positional index bumped up to make room.
a_list.insert(0, value)与Perl中的unshift()函数类似。
Let’s look closer at the difference between append() and extend().
让我们仔细观察下append() 和 extend()间的区别,extend是扩展,有可能增加多项,append是附加一项,只增加一项。
>>> a_list = ['a', 'b', 'c']
>>> a_list.extend(['d', 'e', 'f']) ①
>>> a_list
['a', 'b', 'c', 'd', 'e', 'f']
>>> len(a_list) ②
6
>>> a_list[-1]
'f'
>>> a_list.append(['g', 'h', 'i']) ③
>>> a_list
['a', 'b', 'c', 'd', 'e', 'f', ['g', 'h', 'i']]
>>> len(a_list) ④
7
>>> a_list[-1]
['g', 'h', 'i']
1. The extend() method takes a single argument, which is always a list, and adds each of the items of that list to a_list.
extend()只有一个参数,该参数始终是列表,功能是把该列表的每一项都添加到a_list中。
2. If you start with a list of three items and extend it with a list of another three items, you end up with a list of six items.
对于extend()方法,如果原先列表有3项,参数有3项,则最后为6项。
3. On the other hand, the append() method takes a single argument, which can be any datatype. Here, you’re calling the append() method with a list of three items.
append()方法只使用一个参数,参数可以是任何数据类型。上面的示例中,参数为一个含有3项的列表。
4. If you start with a list of six items and append a list onto it, you end up with... a list of seven items. Why seven? Because the last item (which you just appended) is itself a list. Lists can contain any type of data, including other lists. That may be what you want, or it may not. But it’s what you asked for, and it’s what you got.
对于append()方法,如果原先列表是6项,那么最后结果是7项。因为最后一项就是你所添加的列表本身。列表可以包含任何数据类型,包括列表类型本身。
SEARCHING FOR VALUES IN A LIST
在列表中搜索值
>>> a_list = ['a', 'b', 'new', 'mpilgrim', 'new']
>>> a_list.count('new') ①
2
>>> 'new' in a_list ②
True
>>> 'c' in a_list
False
>>> a_list.index('mpilgrim') ③
3
>>> a_list.index('new') ④
2
>>> a_list.index('c') ⑤
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
1. As you might expect, the count() method returns the number of occurrences of a specific value in a list.
如你所愿,count()返回列表中指定值出现的次数。
2. If all you want to know is whether a value is in the list or not, the in operator is slightly faster than using the count() method. The in operator always returns True or False; it will not tell you where in the list the value is.
如果只想知道列表中是否存在某一值。可以使用 in 操作符,它只返回True 或 False,但不会告诉你值在列表中的索引。
3. If you need to know exactly where in the list a value is, call the index() method. By default it will search the entire list, although you can specify a second argument of the (0-based) index to start from, and even a third argument of the (0-based) index to stop searching.
如果需要某一值在列表中的确切位置,可以使用index()方法。默认情况下,会搜索整个列表,但你也可以指定范围,第2个参数和第3个参数分别代表起始和截至的位置。
4. The index() method finds the first occurrence of a value in the list. In this case, 'new' occurs twice in the list, in a_list[2] and a_list[4], but the index() method will return only the index of the first occurrence.
index()方法会返回参数值在列表中第一次出现的索引。
5. As you might not expect, if the value is not found in the list, the index() method will raise an exception.
如果参数值在列表中不存在,index()方法会抛出异常。
Wait, what? That’s right: the index() method raises an exception if it doesn’t find the value in the list. This is notably different from most languages, which will return some invalid index (like -1). While this may seem annoying at first, I think you will come to appreciate it. It means your program will crash at the source of the problem instead of failing strangely and silently later. Remember, -1 is a valid list index. If the index() method returned -1, that could lead to some not-so-fun debugging sessions!
Index()方法如果在列表中找不到参数值,就会引发异常。这么做和大多数语言都不一样,其他语言可能返回无效索引,例如-1。Ptn这种做法看似有点烦人,但这样做可以让我们更好的定位到问题。而且,-1对于Ptn是一个有效的索引-1 is a valid list index,如果返回-1,那么你可能很难定位到问题。
REMOVING ITEMS FROM A LIST
从列表中删除项
Lists never have gaps.
列表绝不会有空项。
Lists can expand and contract automatically. You’ve seen the expansion part. There are several different ways to remove items from a list as well.
列表可以自动扩展也可以自动收缩。前面已经看到了如何扩展,下面介绍几种删除列表中项的方法。
>>> a_list = ['a', 'b', 'new', 'mpilgrim', 'new']
>>> a_list[1]
'b'
>>> del a_list[1] ①
>>> a_list
['a', 'new', 'mpilgrim', 'new']
>>> a_list[1] ②
'new'
1. You can use the del statement to delete a specific item from a list.
可以使用del语句删除列表中的指定项。
2. Accessing index 1 after deleting index 1 does not result in an error. All items after the deleted item shift their positional index to “fill the gap” created by deleting the item.
在删除索引为1的项后,仍可以访问索引为1的项,因为删除该项后,该项后面的项会前移。
Don’t know the positional index? Not a problem; you can remove items by value instead.
如果不知道所要删除项的索引,可以用值作为参数删除,如下。
>>> a_list.remove('new') ①
>>> a_list
['a', 'mpilgrim', 'new']
>>> a_list.remove('new') ②
>>> a_list
['a', 'mpilgrim']
>>> a_list.remove('new')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
1. You can also remove an item from a list with the remove() method. The remove() method takes a value and removes the first occurrence of that value from the list. Again, all items after the deleted item will have their positional indices bumped down to “fill the gap.” Lists never have gaps.
使用remove()方法,提供一个值作为参数,会删除列表中第一次出现的该值,然后后面所有项前移。
2. You can call the remove() method as often as you like, but it will raise an exception if you try to remove a value that isn’t in the list.
如果remove()方法的参数在列表中不存在,则会引发异常。
REMOVING ITEMS FROM A LIST: BONUS ROUND
从列表中删除项的另外一种方法
Another interesting list method is pop(). The pop() method is yet another way to remove items from a list, but with a twist.
另一种删除列表项的方法是pop(),remove items from a list。
>>> a_list = ['a', 'b', 'new', 'mpilgrim']
>>> a_list.pop() ①
'mpilgrim'
>>> a_list
['a', 'b', 'new']
>>> a_list.pop(1) ②
'b'
>>> a_list
['a', 'new']
>>> a_list.pop()
'new'
>>> a_list.pop()
'a'
>>> a_list.pop() ③
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop from empty list
1. When called without arguments, the pop() list method removes the last item in the list and returns the value it removed.
调用pop()时,如果不传入参数,就会删除列表中的最后一项,并且返回所删除项的值。
2. You can pop arbitrary items from a list. Just pass a positional index to the pop() method. It will remove that item, shift all the items after it to “fill the gap,” and return the value it removed.
你可以pop列表中的任意项,只要把索引作为参数传递给pop()即可。它会返回该项值,并且后面的项会自动前移。
3. Calling pop() on an empty list raises an exception.
对空列表使用pop()方法会引发异常。
☞Calling the pop() list method without an argument is like the pop() function in Perl. It removes the last item from the list and returns the value of the removed item. Perl has another function, shift(), which removes the first item and returns its value; in Python, this is equivalent to a_list.pop(0).
Ptn中的a_list.pop(0)中的方法和Perl中的shift()方法的效果一样。
LISTS IN A BOOLEAN CONTEXT
布尔上下文中的列表
Empty lists are false; all other lists are true.
空列表是false,其他列表都为true。
You can also use a list in a boolean context, such as an if statement.
你还可以在列表上下文中(a boolean context),使用列表,例如if语句
>>> def is_it_true(anything):
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true([]) ①
no, it's false
>>> is_it_true(['a']) ②
yes, it's true
>>> is_it_true([False]) ③
yes, it's true
1. In a boolean context, an empty list is false.
在布尔上下文中,空列表是false
2. Any list with at least one item is true.
列表中只要有一项就是true.
3. Any list with at least one item is true. The value of the items is irrelevant.
无论列表中值为什么,只要有项,就是true.
⁂
TUPLES
元组,这个容易和列表混淆,可以这样记忆,元通圆,所以元组是圆括号,而列表不是圆括号
A tuple is an immutable list. A tuple can not be changed in any way once it is created.
元组是不可改变的列表,一旦被创建,里面的元素就无法被改变。
>>> a_tuple = ("a", "b", "mpilgrim", "z", "example") ①
>>> a_tuple
('a', 'b', 'mpilgrim', 'z', 'example')
>>> a_tuple[0] ②
'a'
>>> a_tuple[-1] ③
'example'
>>> a_tuple[1:3] ④
('b', 'mpilgrim')
1. A tuple is defined in the same way as a list, except that the whole set of elements is enclosed in parentheses instead of square brackets.
元组的定义方法与列表一样,只是用圆括号圈起来。
2. The elements of a tuple have a defined order, just like a list. Tuple indices are zero-based, just like a list, so the first element of a non-empty tuple is always a_tuple[0].
元组中元素排列的顺序是在定义时确定的。所以非空列表的第一个元素始终是a_tuple[0]。
3. Negative indices count from the end of the tuple, just like a list.
负数索引和列表的规定一样。
4. Slicing works too, just like a list. When you slice a list, you get a new list; when you slice a tuple, you get a new tuple.
元组也支持分片。对列表分片,会得到新列表。对元组分片,会得到新元组。
The major difference between tuples and lists is that tuples can not be changed. In technical terms, tuples are immutable. In practical terms, they have no methods that would allow you to change them. Lists have methods like append(), extend(), insert(), remove(), and pop(). Tuples have none of these methods. You can slice a tuple (because that creates a new tuple), and you can check whether a tuple contains a particular value (because that doesn’t change the tuple), and… that’s about it.
元组和列表的主要不同是,元组内容是无法改变的。列表有append(), extend(), insert(), remove(), 和 pop()等方法。元组这些方法一个都没有。你可以对元组分片(因为这会创建一个新元组),你还可以检查元组是否包含特定值(因为这样并不会改变元组)
# continued from the previous example
>>> a_tuple
('a', 'b', 'mpilgrim', 'z', 'example')
>>> a_tuple.append("new") ①
Traceback (innermost last):
File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'append'
>>> a_tuple.remove("z") ②
Traceback (innermost last):
File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'remove'
>>> a_tuple.index("example") ③
4
>>> "z" in a_tuple ④
True
1. You can’t add elements to a tuple. Tuples have no append() or extend() method.
无法向元组中添加元素。元组没有append()和 extend()方法。
2. You can’t remove elements from a tuple. Tuples have no remove() or pop() method.
无法从元组中删除元素。元组没有remove() 和pop()方法。
3. You can find elements in a tuple, since this doesn’t change the tuple.
可以查找元组中的元素,因为这样不会改变元组。
4. You can also use the in operator to check if an element exists in the tuple.
也可以使用 in 操作符,检查元组中是否存在某一元素。
So what are tuples good for?
那么到底什么情况下适合使用元组呢?
• Tuples are faster than lists. If you’re defining a constant set of values and all you’re ever going to do with it is iterate through it, use a tuple instead of a list.
元组要比列表快。如果你打算定义一个不会改变的集合,并且只是需要遍历,那么这时元组就比列表更快。
• It makes your code safer if you “write-protect” data that doesn’t need to be changed. Using a tuple instead of a list is like having an implied assert statement that shows this data is constant, and that special thought (and a specific function) is required to override that.
元组可以让你对数据进行“写保护”,这样就不会发生意外改变的情况。
• Some tuples can be used as dictionary keys (specifically, tuples that contain immutable values like strings, numbers, and other tuples). Lists can never be used as dictionary keys, because lists are not immutable.
某些元组可以用作字典的键值,列表则不可以,因为列表中的元素是可以改变的。
☞Tuples can be converted into lists, and vice-versa. The built-in tuple() function takes a list and returns a tuple with the same elements, and the list() function takes a tuple and returns a list. In effect, tuple() freezes a list, and list() thaws a tuple.
元组和列表可以互相转换。Tuple()函数可以将列表转换为元组。list()函数可以将元组转换为列表。
TUPLES IN A BOOLEAN CONTEXT
布尔上下文中的元组
You can use tuples in a boolean context, such as an if statement.
你可以在布尔上下文中使用元组,例如,if语句
>>> def is_it_true(anything):
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true(()) ①
no, it's false
>>> is_it_true(('a', 'b')) ②
yes, it's true
>>> is_it_true((False,)) ③
yes, it's true
>>> type((False)) ④
<class 'bool'>
>>> type((False,))
<class 'tuple'>
1. In a boolean context, an empty tuple is false.
在布尔上下文中,空元组是false.
2. Any tuple with at least one item is true.
元组中只要有一个值就是true.
3. Any tuple with at least one item is true. The value of the items is irrelevant. But what’s that comma doing there?
元组中只要有一个值就是true,无论给值为什么。那么这里的逗号是干吗用的呢?
4. To create a tuple of one item, you need a comma after the value. Without the comma, Python just assumes you have an extra pair of parentheses, which is harmless, but it doesn’t create a tuple.
若要创建一个只含有一个元素的元组,需要在该元素后面加一个逗号。没有逗号,Ptn就会认为两个圆括号只是括号,并不是要定义一个元组。
ASSIGNING MULTIPLE VALUES AT ONCE
一次赋多个值
Here’s a cool programming shortcut: in Python, you can use a tuple to assign multiple values at once.
现在给大家讲一种非常酷的编程技巧,我们可以一次为元组中的多个元素赋值。
>>> v = ('a', 2, True)
>>> (x, y, z) = v ①
>>> x
'a'
>>> y
2
>>> z
True
1. v is a tuple of three elements, and (x, y, z) is a tuple of three variables. Assigning one to the other assigns each of the values of v to each of the variables, in order.
V是一个含有三个元素的元组,(x, y, z)是一个含有3个变量的元组。X,y,z将顺序赋值为 ‘a’, 2 , True.
This has all kinds of uses. Suppose you want to assign names to a range of values. You can use the built-in range() function with multi-variable assignment to quickly assign consecutive values.
假设你想为一串名字赋一串连续的值。可以使用内置函数range(),快速完成顺序赋值。
>>> (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) ①
>>> MONDAY ②
0
>>> TUESDAY
1
>>> SUNDAY
6
1. The built-in range() function constructs a sequence of integers. (Technically, the range() function returns an iterator, not a list or a tuple, but you’ll learn about that distinction later.) MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, and SUNDAY are the variables you’re defining. (This example came from the calendar module, a fun little module that prints calendars, like the UNIX program cal. The calendar module defines integer constants for days of the week.)
内置函数range()可以生成一串连续的整数。(技术上讲,range()函数返回一个迭代器iterator,而并非返回的是列表或元组,后面我们会详细讲iterator)。MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, 和 SUNDAY是所定义的变量。
2. Now each variable has its value: MONDAY is 0, TUESDAY is 1, and so forth.
现在每个变量都有了自己的值,MONDAY 是 0, TUESDAY 是 1,依此类推。
You can also use multi-variable assignment to build functions that return multiple values, simply by returning a tuple of all the values. The caller can treat it as a single tuple, or it can assign the values to individual variables. Many standard Python libraries do this, including the os module, which you'll learn about in the next chapter.
依靠多变量同时赋值,我们还可以设计一个函数返回多个值,这些值放在单一一个元组中返回。调用的时候,因为返回的是一个元组,所以我们就可以轻松地为外部的多个变量同时赋值。许多标准的Ptn库都是这么做的,包括os模块——下一章将会学习到。
⁂
SETS
集合
A set is an unordered “bag” of unique values. A single set can contain values of any datatype. Once you have a two sets, you can do standard set operations like union, intersection, and set difference.
集合是一包不按键入顺序排列的,且不允许重复的值。集合可以包含任意数据类型的值。如果有两个集合,则可以执行一些标准的操作,例如,union, intersection, 和 set difference。
CREATING A SET
创建集合
First things first. Creating a set is easy.
创建集合非常简单。
>>> a_set = {1} ①
>>> a_set
{1}
>>> type(a_set) ②
<class 'set'>
>>> a_set = {1, 2} ③
>>> a_set
{1, 2}
1. To create a set with one value, put the value in curly brackets ({}).
使用花括号创建集合。
2. Sets are actually implemented as classes, but don’t worry about that for now.
集合也是类。
3. To create a set with multiple values, separate the values with commas and wrap it all up with curly brackets.
创建含有多个值的集合,需要用逗号分割每个值。
You can also create a set out of a list.
还可以通过列表创建集合。
>>> a_list = ['a', 'b', 'mpilgrim', True, False, 42]
>>> a_set = set(a_list) ①
>>> a_set ②
{'a', False, 'b', True, 'mpilgrim', 42}
>>> a_list ③
['a', 'b', 'mpilgrim', True, False, 42]
1. To create a set from a list, use the set() function. (Pedants who know about how sets are implemented will point out that this is not really calling a function, but instantiating a class. I promise you will learn the difference later in this book. For now, just know that set() acts like a function, and it returns a set.)
若要通过列表创建集合,请使用set()函数(其实不是调用函数,而是实例化一个类,后面我们会详细说明,现在你就暂且认为是通过调用函数来返回一个集合)。
2. As I mentioned earlier, a single set can contain values of any datatype. And, as I mentioned earlier, sets are unordered. This set does not remember the original order of the list that was used to create it. If you were to add items to this set, it would not remember the order in which you added them.
上面说到集合可以包含任何数据类型的值,以及集合中元素的顺序与定义时的顺序并不一致。如果你要向集合中添加项,集合并不会记住你添加它们的顺序。
3. The original list is unchanged.
原先的列表并未被改变。
Don’t have any values yet? Not a problem. You can create an empty set.
如果没有值,你也可以创建一个空集合。
>>> a_set = set() ①
>>> a_set ②
set()
>>> type(a_set) ③
<class 'set'>
>>> len(a_set) ④
0
>>> not_sure = {} ⑤
>>> type(not_sure)
<class 'dict'>
1. To create an empty set, call set() with no arguments.
若要创建空集合,直接调用set()。
2. The printed representation of an empty set looks a bit strange. Were you expecting {}, perhaps? That would denote an empty dictionary, not an empty set. You’ll learn about dictionaries later in this chapter.
你也许想返回的应该是{}。但实际上{}是表示空字典的意思,而不是空集合。本章稍后我们会讲到字典。
3. Despite the strange printed representation, this is a set…
类型为集合。
4. …and this set has no members.
该集合没有成员。
5. Due to historical quirks carried over from Python 2, you can not create an empty set with two curly brackets. This actually creates an empty dictionary, not an empty set.
使用{}创建的实际是空字典,而不是空集合
MODIFYING A SET
修改集合
There are two different ways to add values to an existing set: the add() method, and the update() method.
有两种方法向集合中添加元素,add()方法和update()方法。
>>> a_set = {1, 2}
>>> a_set.add(4) ①
>>> a_set
{1, 2, 4}
>>> len(a_set) ②
3
>>> a_set.add(1) ③
>>> a_set
{1, 2, 4}
>>> len(a_set) ④
3
1. The add() method takes a single argument, which can be any datatype, and adds the given value to the set.
Add()方法只有一个参数,可以是任何类型,该值将会添加到集合中。
2. This set now has 3 members.
该集合现在有了3个成员。
3. Sets are bags of unique values. If you try to add a value that already exists in the set, it will do nothing. It won’t raise an error; it’s just a no-op.
集合中都是不重复的值。如果添加一个已经存在的值到集合中,集合并不会发生变化,也不会引发异常。
4. This set still has 3 members.
该集合仍是3个元素。
>>> a_set = {1, 2, 3}
>>> a_set
{1, 2, 3}
>>> a_set.update({2, 4, 6}) ①
>>> a_set ②
{1, 2, 3, 4, 6}
>>> a_set.update({3, 6, 9}, {1, 2, 3, 5, 8, 13}) ③
>>> a_set
{1, 2, 3, 4, 5, 6, 8, 9, 13}
>>> a_set.update([10, 20, 30]) ④
>>> a_set
{1, 2, 3, 4, 5, 6, 8, 9, 10, 13, 20, 30}
1. The update() method takes one argument, a set, and adds all its members to the original set. It’s as if you called the add() method with each member of the set.
update()方法使用了一个集合作为参数,将该参数的所有元素添加到原来的集合中。
2. Duplicate values are ignored, since sets can not contain duplicates.
重复值被忽略,因为集合不允许包含重复的值。
3. You can actually call the update() method with any number of arguments. When called with two sets, the update() method adds all the members of each set to the original set (dropping duplicates).
实际上,update可以接受任意多个参数,并把每个参数的所有成员添加到原来的集合中,且忽略掉重复的值。
4. The update() method can take objects of a number of different datatypes, including lists. When called with a list, the update() method adds all the items of the list to the original set.
update()方法的参数可以接受不同数据类型的对象,包括列表。在调用列表时,update()方法将列表中的所有元素添加到原来的集合中。
REMOVING ITEMS FROM A SET
删除集合中的项
There are three ways to remove individual values from a set. The first two, discard() and remove(), have one subtle difference.
有2种方法。
>>> a_set = {1, 3, 6, 10, 15, 21, 28, 36, 45}
>>> a_set
{1, 3, 36, 6, 10, 45, 15, 21, 28}
>>> a_set.discard(10) ①
>>> a_set
{1, 3, 36, 6, 45, 15, 21, 28}
>>> a_set.discard(10) ②
>>> a_set
{1, 3, 36, 6, 45, 15, 21, 28}
>>> a_set.remove(21) ③
>>> a_set
{1, 3, 36, 6, 45, 15, 28}
>>> a_set.remove(21) ④
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 21
1. The discard() method takes a single value as an argument and removes that value from the set.
discard()把集合中与参数值相等的项删除。
2. If you call the discard() method with a value that doesn’t exist in the set, it does nothing. No error; it’s just a no-op.
discard()参数值若在集合中不存在,不会引发异常,只是一个空操作。
3. The remove() method also takes a single value as an argument, and it also removes that value from the set.
Remove()把集合中与参数值相等的项删除。
4. Here’s the difference: if the value doesn’t exist in the set, the remove() method raises a KeyError exception.
Remove()参数值若在集合中不存在,会引发KeyError异常。
Like lists, sets have a pop() method.
集合像列表一样也有pop()方法。
>>> a_set = {1, 3, 6, 10, 15, 21, 28, 36, 45}
>>> a_set.pop() ①
1
>>> a_set.pop()
3
>>> a_set.pop()
36
>>> a_set
{6, 10, 45, 15, 21, 28}
>>> a_set.clear() ②
>>> a_set
set()
>>> a_set.pop() ③
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'pop from an empty set'
1. The pop() method removes a single value from a set and returns the value. However, since sets are unordered, there is no “last” value in a set, so there is no way to control which value gets removed. It is essentially random.
Pop()方法删除一个元素,并返回该元素的值。但是,因为集合是无序的,所有没法控制pop出的是哪个值,实际上是随机的。
2. The clear() method removes all values from a set, leaving you with an empty set. This is equivalent to a_set = set(), which would create a new empty set and overwrite the previous value of the a_set variable.
Clear()方法删除集合中的所有元素,只剩一个空集合。这等价于a_set = set()——创建一个新的空集合并覆盖a_set变量之前的值。
3. Attempting to pop a value from an empty set will raise a KeyError exception.
对空列表调用pop()方法会引发KeyError异常。
COMMON SET OPERATIONS
对集合常用的操作
Python’s set type supports several common set operations.
Set类型有多个常用的操作。
>>> a_set = {2, 4, 5, 9, 12, 21, 30, 51, 76, 127, 195}
>>> 30 in a_set ①
True
>>> 31 in a_set
False
>>> b_set = {1, 2, 3, 5, 6, 8, 9, 12, 15, 17, 18, 21}
>>> a_set.union(b_set) ②
{1, 2, 195, 4, 5, 6, 8, 12, 76, 15, 17, 18, 3, 21, 30, 51, 9, 127}
>>> a_set.intersection(b_set) ③
{9, 2, 12, 5, 21}
>>> a_set.difference(b_set) ④
{195, 4, 76, 51, 30, 127}
>>> a_set.symmetric_difference(b_set) ⑤
{1, 3, 4, 6, 8, 76, 15, 17, 18, 195, 127, 30, 51}
1. To test whether a value is a member of a set, use the in operator. This works the same as lists.
使用 in 操作符判断集合中是否存在某一元素。
2. The union() method returns a new set containing all the elements that are in either set.
union()方法将两个集合中的元素整合在一起。
3. The intersection() method returns a new set containing all the elements that are in both sets.
intersection()方法返回两个集合中共有的元素。
4. The difference() method returns a new set containing all the elements that are in a_set but not b_set.
difference()返回集合a_set中含有但b_set中不含有的元素。
5. The symmetric_difference() method returns a new set containing all the elements that are in exactly one of the sets.
symmetric_difference()返回的是两个集合中,不共同含有的元素。
Three of these methods are symmetric.
这些方法中有三个方法是对称的,请看下面的示例。
# continued from the previous example
>>> b_set.symmetric_difference(a_set) ①
{3, 1, 195, 4, 6, 8, 76, 15, 17, 18, 51, 30, 127}
>>> b_set.symmetric_difference(a_set) == a_set.symmetric_difference(b_set) ②
True
>>> b_set.union(a_set) == a_set.union(b_set) ③
True
>>> b_set.intersection(a_set) == a_set.intersection(b_set) ④
True
>>> b_set.difference(a_set) == a_set.difference(b_set) ⑤
False
1. The symmetric difference of a_set from b_set looks different than the symmetric difference of b_set from a_set, but remember, sets are unordered. Any two sets that contain all the same values (with none left over) are considered equal.
a_set.symmetric_difference(b_set)和b_set.symmetric_difference(a_set)返回的集合中元素的顺序虽然不同,但请记住,集合中元素排列是不分顺序的。任何两个集合中的元素数量和值都相等就认为两个集合是相同的。
2. And that’s exactly what happens here. Don’t be fooled by the Python Shell’s printed representation of these sets. They contain the same values, so they are equal.
和上面的解释一样
3. The union of two sets is also symmetric.
对两个集合的union操作也是对称的。
4. The intersection of two sets is also symmetric.
对两个集合的intersection操作也是对称的。
5. The difference of two sets is not symmetric. That makes sense; it’s analogous to subtracting one number from another. The order of the operands matters.
对两个集合的difference操作不是对称的。这很容易理解。
Finally, there are a few questions you can ask of sets.
最后,还有一些对集合的操作。
>>> a_set = {1, 2, 3}
>>> b_set = {1, 2, 3, 4}
>>> a_set.issubset(b_set) ①
True
>>> b_set.issuperset(a_set) ②
True
>>> a_set.add(5) ③
>>> a_set.issubset(b_set)
False
>>> b_set.issuperset(a_set)
False
1. a_set is a subset of b_set — all the members of a_set are also members of b_set.
a_set是b_set的子集。即,a_set 中的所有元素都是b_set 中的元素。
2. Asking the same question in reverse, b_set is a superset of a_set, because all the members of a_set are also members of b_set.
b_set是a_set的超集。因为a_set的所有成员也是b_set的成员
3. As soon as you add a value to a_set that is not in b_set, both tests return False.
现在,两个集合不再有包含关系。
SETS IN A BOOLEAN CONTEXT
布尔上下文中的集合
You can use sets in a boolean context, such as an if statement.
可以在布尔上下文中使用集合,例如,if语句
>>> def is_it_true(anything):
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true(set()) ①
no, it's false
>>> is_it_true({'a'}) ②
yes, it's true
>>> is_it_true({False}) ③
yes, it's true
1. In a boolean context, an empty set is false.
在布尔上下文中,空集合代表false
2. Any set with at least one item is true.
非空集合代表true.
3. Any set with at least one item is true. The value of the items is irrelevant.
非空集合代表true,无论其中值是什么。
⁂
DICTIONARIES
字典
A dictionary is an unordered set of key-value pairs. When you add a key to a dictionary, you must also add a value for that key. (You can always change the value later.) Python dictionaries are optimized for retrieving the value when you know the key, but not the other way around.
字典是一个不按顺序排列的键值对集合。在向字典添加键时,还必须同时提供对应的值(该值是可以在随后改变的)。Ptn在内部为值的检索进行了优化。
☞A dictionary in Python is like a hash in Perl 5. In Perl 5, variables that store hashes always start with a % character. In Python, variables can be named anything, and Python keeps track of the datatype internally.
Ptn中的字典与Perl 5 中的哈希类似。在Perl 5中,存储哈希的变量始终以%字符开头。在Ptn中,变量名是没有限制的,Ptn内部会自动跟踪该变量。
CREATING A DICTIONARY
创建字典
Creating a dictionary is easy. The syntax is similar to sets, but instead of values, you have key-value pairs. Once you have a dictionary, you can look up values by their key.
创建字典很简单,语法与集合类似,但使用的是键值对。创建字典后,就可以通过键来查找对应的值。
>>> a_dict = {'server': 'db.diveintopython3.org', 'database': 'mysql'} ①
>>> a_dict
{'server': 'db.diveintopython3.org', 'database': 'mysql'}
>>> a_dict['server'] ②
'db.diveintopython3.org'
>>> a_dict['database'] ③
'mysql'
>>> a_dict['db.diveintopython3.org'] ④
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'db.diveintopython3.org'
1. First, you create a new dictionary with two items and assign it to the variable a_dict. Each item is a key-value pair, and the whole set of items is enclosed in curly braces.
首先,创建一个含有2个元素的新字典,并将其赋值给变量a_dict。每个元素都是一个键值对,整个集合都用花括号括起来。
2. 'server' is a key, and its associated value, referenced by a_dict['server'], is 'db.diveintopython3.org'.
‘server’是一个键,它对应的值'db.diveintopython3.org'可以用a_dict['server']来引用。
3. 'database' is a key, and its associated value, referenced by a_dict['database'], is 'mysql'.
‘database’是一个键,它对应的值' mysql '可以用a_dict['server']来引用。
4. You can get values by key, but you can’t get keys by value. So a_dict['server'] is 'db.diveintopython3.org', but a_dict['db.diveintopython3.org'] raises an exception, because 'db.diveintopython3.org' is not a key.
可以通过键得到值,但反之则不可以。所以a_dict['db.diveintopython3.org']会引发异常。
MODIFYING A DICTIONARY
修改字典
Dictionaries do not have any predefined size limit. You can add new key-value pairs to a dictionary at any time, or you can modify the value of an existing key. Continuing from the previous example:
字典不预设置大小,可以随时添加新的键值对,或修改现有的键对应的值。下面,我们继续扩展上个示例:
>>> a_dict
{'server': 'db.diveintopython3.org', 'database': 'mysql'}
>>> a_dict['database'] = 'blog' ①
>>> a_dict
{'server': 'db.diveintopython3.org', 'database': 'blog'}
>>> a_dict['user'] = 'mark' ②
>>> a_dict ③
{'server': 'db.diveintopython3.org', 'user': 'mark', 'database': 'blog'}
>>> a_dict['user'] = 'dora' ④
>>> a_dict
{'server': 'db.diveintopython3.org', 'user': 'dora', 'database': 'blog'}
>>> a_dict['User'] = 'mark' ⑤
>>> a_dict
{'User': 'mark', 'server': 'db.diveintopython3.org', 'user': 'dora', 'database': 'blog'}
1. You can not have duplicate keys in a dictionary. Assigning a value to an existing key will wipe out the old value.
字典中不能有重复的键,为现存的键赋值,会清除掉原来的值。
2. You can add new key-value pairs at any time. This syntax is identical to modifying existing values.
可以随时添加键值对,语法和修改现有值是一样的。
3. The new dictionary item (key 'user', value 'mark') appears to be in the middle. In fact, it was just a coincidence that the items appeared to be in order in the first example; it is just as much a coincidence that they appear to be out of order now.
新添加的字典项(键为’user’,值为’mark’),出现在中间。实际上,在第一个示例中,只是偶然键入的顺序和显示的顺序是一样的。而现在,也只不过是碰巧不一样。
4. Assigning a value to an existing dictionary key simply replaces the old value with the new one.
为现有字典赋值只是用新值替换旧值。
5. Will this change the value of the user key back to "mark"? No! Look at the key closely — that’s a capital U in "User". Dictionary keys are case-sensitive, so this statement is creating a new key-value pair, not overwriting an existing one. It may look similar to you, but as far as Python is concerned, it’s completely different.
键名是大小写敏感的。
MIXED-VALUE DICTIONARIES
混合各种类型的值的字典
Dictionaries aren’t just for strings. Dictionary values can be any datatype, including integers, booleans, arbitrary objects, or even other dictionaries. And within a single dictionary, the values don’t all need to be the same type; you can mix and match as needed. Dictionary keys are more restricted, but they can be strings, integers, and a few other types. You can also mix and match key datatypes within a dictionary.
字典不止只用于字符串。字典值可以是任何数据类型,包括整数、布尔值和任意对象,甚至于字典本身。对于单个字典,其中的值不需要都是同一类型。可以按照需要使用各种类型。字典的键会有一些限制,可以是字符串、整数和其他一些类型。我们也可以在字典内,混合使用和匹配不同类型的键。
In fact, you’ve already seen a dictionary with non-string keys and values, in your first Python program.
实际上,在你的第一个Ptn程序中your first Python program.,我们已经看到一个使用了非字符串键的字典。
SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
Let's tear that apart in the interactive shell.
我们节选了一部分内容。
>>> SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
... 1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
>>> len(SUFFIXES) ①
2
>>> 1000 in SUFFIXES ②
True
>>> SUFFIXES[1000] ③
['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
>>> SUFFIXES[1024] ④
['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
>>> SUFFIXES[1000][3] ⑤
'TB'
1. Like lists and sets, the len() function gives you the number of keys in a dictionary.
与列表和集合类似,len()函数给出字典中键的数量。
2. And like lists and sets, you can use the in operator to test whether a specific key is defined in a dictionary.
与列表和集合类似,可以使用 in 操作符测试字典中是否包含具体的键。
3. 1000 is a key in the SUFFIXES dictionary; its value is a list of eight items (eight strings, to be precise).
1000是字典中的一个键,它的值是一个含有8个元素的列表。
4. Similarly, 1024 is a key in the SUFFIXES dictionary; its value is also a list of eight items.
类似,1024是字典中的一个键,它的值是一个含有8个元素的列表。
5. Since SUFFIXES[1000] is a list, you can address individual items in the list by their 0-based index.
因为SUFFIXES[1000]是一个列表,所以可以通过索引引用其中的单个值。
DICTIONARIES IN A BOOLEAN CONTEXT
布尔上下文中的字典
Empty dictionaries are false; all other dictionaries are true.
空字典是false,其他都是true。
You can also use a dictionary in a boolean context, such as an if statement.
可以在if语句中使用字典。
>>> def is_it_true(anything):
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true({}) ①
no, it's false
>>> is_it_true({'a': 1}) ②
yes, it's true
1. In a boolean context, an empty dictionary is false.
2. Any dictionary with at least one key-value pair is true.
空字典是false,其他都是true。
⁂
NONE
None is a special constant in Python. It is a null value. None is not the same as False. None is not 0. None is not an empty string. Comparing None to anything other than None will always return False.
None 是Ptn中的特殊常量,它表示null值。None与False不同,也不是0,也不是空字符串。None只等于None,不等于其他任何类型的任何值。
None is the only null value. It has its own datatype (NoneType). You can assign None to any variable, but you can not create other NoneType objects. All variables whose value is None are equal to each other.
None只是一个null值,它有自己的数据类型(NoneType)。可以将None赋值给任何变量,但不能创建其他NoneType对象。所有值为None的变量是相等的。
>>> type(None)
<class 'NoneType'>
>>> None == False
False
>>> None == 0
False
>>> None == ''
False
>>> None == None
True
>>> x = None
>>> x == None
True
>>> y = None
>>> x == y
True
NONE IN A BOOLEAN CONTEXT
NONE在布尔上下文中
In a boolean context, None is false and not None is true.
在布尔上下文中,None是false,而not None是true。
>>> def is_it_true(anything):
... if anything:
... print("yes, it's true")
... else:
... print("no, it's false")
...
>>> is_it_true(None)
no, it's false
>>> is_it_true(not None)
yes, it's true
⁂
FURTHER READING
• Boolean operations
• Numeric types
• Sequence types
• Set types
• Mapping types
• fractions module
• math module
• PEP 237: Unifying Long Integers and Integers
• PEP 238: Changing the Division Operator
☜ ☞
© 2001–9 Mark Pilgrim