一、你好,python
简介
本课程涵盖您将需要的关键Python技能,以便您可以开始使用Python进行数据科学。本课程非常适合那些有过一些编程经验的人,他们希望将Python添加到他们的技能库中,或者提升他们的基本Python技能(如果您是第一次编写代码,您可能需要查看这些“面向非程序员的Python”学习资源。)
我们将从Python语法、变量赋值和算术运算符的简要概述开始。如果您以前有Python经验,可以直接跳到实践练习。
你好,python!
Python是以英国喜剧团montypython命名的,所以我们将把我们的第一个Python程序作为对他们关于Spam的小品的致敬?
只是为了好玩,试着阅读下面的代码,并预测它运行时将要做什么(如果你不知道,那很好!)
然后点击“输出”按钮查看我们程序的结果。
spam_amount = 0
print(spam_amount)
# 订购垃圾邮件、鸡蛋、垃圾邮件、垃圾邮件、培根和垃圾邮件(4份垃圾邮件)
spam_amount = spam_amount + 4
if spam_amount > 0:
print("But I don't want ANY spam!")
viking_song = "Spam " * spam_amount
print(viking_song)
这里有很多东西要打开!这个愚蠢的程序演示了Python代码的许多重要方面以及它是如何工作的。让我们从上到下检查代码。
spam_amount = 0
变量赋值:在这里,我们创建一个名为spam_amount的变量,并使用=,将其赋值为0,这称为赋值运算符。
旁白:如果你已经用其他语言(比如java或C++)编程,你可能会注意到Python不需要我们做的一些事情:
在分配给它之前,我们不需要“声明”垃圾邮件数量
我们不需要告诉Python spam_amount将引用什么类型的值。事实上,我们甚至可以继续重新分配spam_amount,以引用不同类型的东西,比如字符串或布尔值。
print(spam_amount)
功能calls:. print是一个Python函数,它在屏幕上显示传递给它的值。我们调用函数的方法是将括号放在函数名之后,并将函数的输入(或参数)放在这些括号中。
# 订购垃圾邮件,鸡蛋,垃圾邮件,垃圾邮件,培根和垃圾邮件(4份以上的垃圾邮件)
spam_amount = spam_amount + 4
上面第一行是评论。在Python中,注释以#符号开头。
接下来我们将看到一个重新分配的示例。重新分配现有变量的值看起来与创建变量一样-它仍然使用=赋值运算符。
在本例中,我们分配给spam\u amount的值涉及到它以前的值的一些简单算法。当遇到这一行时,Python计算=(0+4=4)右侧的表达式,然后将该值赋给左侧的变量。
if spam_amount > 0:
print("But I don't want ANY spam!")
viking_song = "Spam Spam Spam"
print(viking_song)
我们稍后才会讨论“条件句”,但是,即使您以前从未编写过代码,您也可能猜到它的作用。Python以其可读性和简单性而备受推崇。
注意我们是如何指出哪些代码属于if的。”但我不想要任何垃圾邮件!”只有垃圾邮件数量为正时才应该打印。但是后面的代码(比如print(vikingèu song))无论如何都应该执行。我们(和Python)是怎么知道的?
if行末尾的冒号(:)表示新的“代码块”正在启动。缩进的后续行是该代码块的一部分。其他一些语言使用{大括号}来标记代码块的开始和结束。Python使用有意义的空格对于习惯于其他语言的程序员来说可能是令人惊讶的,但实际上,与不强制执行代码块缩进的语言相比,它可以产生更一致和可读的代码。
后面处理viking_song的行没有用额外的4个空格缩进,因此它们不是if代码块的一部分。稍后在定义函数和使用循环时,我们将看到更多缩进代码块的示例。
这段代码片段也是我们在Python中第一次看到字符串:
"But I don't want ANY spam!"
字符串可以用双引号或单引号进行标记(但是由于这个特定的字符串包含一个单引号字符,我们可能会混淆Python,试图用单引号将其括起来,除非我们很小心。)
viking_song = "Spam " * spam_amount
print(viking_song)
*运算符可以用来乘以两个数字(3*3等于9),但有趣的是,我们还可以用一个数字乘以一个字符串,得到一个重复了那么多次的版本。Python提供了许多厚脸皮的节省时间的小技巧,比如,*和+操作符根据它们应用于什么类型的对象而有不同的含义(技术术语是操作员过载)
Python中的数字与算术
我们已经看到了一个包含上述数字的变量示例:
spam_amount = 0
“Number”是这类事物的一个很好的非正式名称,但是如果我们想更具技术性,我们可以问Python它将如何描述spam的类型:
type(spam_amount)
int是整数的缩写。在Python中,我们通常会遇到另一种数字:
type(19.95)
浮点数是一个带小数位的数字,对于表示重量或比例非常有用。
type()是我们看到的第二个内置函数(在print()之后),它是另一个值得记住的函数。能够问Python“这是什么类型的东西?”是非常有用的。
用数字做一件自然的事就是做算术。我们见过加法的+运算符,乘法的*运算符(某种类型)。Python还介绍了计算器上的其他基本按钮:
Operator | Name | Description |
---|---|---|
a + b | Addition | Sum of a and b |
a - b | Subtraction | Difference of a and b |
a * b | Multiplication | Product of a and b |
a / b | True division | Quotient of a and b |
a // b | Floor division | Quotient of a and b , removing fractional parts |
a % b | Modulus | Integer remainder after division of a by b |
a ** b | Exponentiation | a raised to the power of b |
-a | Negation | The negative of a |
一个有趣的观察结果是,虽然您的计算器可能只有一个除法按钮,但Python可以执行两种操作。”真正的除法”基本上就是你的计算器所做的:
print(5 / 2)
print(6 / 2)
它总是给我们一个float。
//运算符给出一个向下舍入到下一个整数的结果。
你能想到这在哪里有用吗?不久您将在编码挑战中看到一个示例。
操作顺序
我们在小学学的算术对运算的顺序有约定。有些人通过一个助记符来记住这些,比如圆括号、指数、乘法/除法、加法/减法。
Python遵循类似的规则,首先执行哪些计算。它们大部分都很直观。
有时,默认的操作顺序不是我们想要的:
hat_height_cm = 25
my_height_cm = 190
# How tall am I, in meters, when wearing my hat?
total_height_meters = hat_height_cm + my_height_cm / 100
print("Height in meters =", total_height_meters, "?")
括号在这里很有用。您可以添加它们来强制Python以您想要的任何顺序计算子表达式。
total_height_meters = (hat_height_cm + my_height_cm) / 100
print("Height in meters =", total_height_meters)
用于处理数字的内置函数
min和max分别返回参数的最小值和最大值...
print(min(1, 2, 3))
print(max(1, 2, 3))
abs返回it参数的绝对值:
print(abs(32))
print(abs(-32))
int和float除了是Python的两个主要数值类型的名称外,还可以作为函数调用,将它们的参数转换为相应的类型:
print(float(10))
print(int(3.33))
# 他们甚至可以在字符串上调用!
print(int('807') + 1)
二、功能和获取帮助
您已经看到并使用了打印和abs等功能。但是Python有很多功能,定义自己的函数是Python编程的一个重要部分。
在本课程中,您将了解更多关于使用和定义函数的知识。
获取帮助
您在上一个教程中看到了abs函数,但是如果您忘记了它的功能呢?
help()函数可能是您可以学习的最重要的Python函数。如果您能记住如何使用help(),那么您就掌握了理解大多数其他函数的关键。
举个例子:
help(round)
help()显示两个内容:
1.该函数的标头round(number,ndigits=None)。在本例中,这告诉我们round()接受一个可以用数字来描述的参数。另外,我们可以选择给出一个单独的参数,可以用ndigits来描述。
2.函数功能的简要英文描述。
常见的陷阱:在查找函数时,请记住传递函数本身的名称,而不是调用该函数的结果。
如果我们在调用函数round()时调用help会发生什么?取消隐藏下面单元格的输出以查看。
help(round(-2.01))
Python从内到外对这样的表达式求值。它首先计算round(-2.01)的值,然后提供有关该表达式输出的帮助。
(事实证明,关于整数有很多要说的!在我们稍后讨论Python中的对象、方法和属性之后,上面的帮助输出将更有意义。)
round是一个非常简单的函数,带有一个短docstring。在处理更复杂的、可配置的功能(如打印)时,帮助会更加突出。如果以下输出看起来难以理解,请不要担心。。。现在,看看你能不能从这个帮助中找到新的东西。
help(print)
如果您正在寻找它,您可能会了解print可以接受一个名为sep的参数,这描述了我们在打印其他参数时将它们放在其他所有参数之间的内容。
定义函数
内置函数很好,但在我们开始定义自己的函数之前,我们只能使用它们。下面是一个简单的例子。
def least_difference(a, b, c):
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
return min(diff1, diff2, diff3)
这将创建一个名为least_difference的函数,它接受三个参数a、b和c。
函数以def关键字引入的标题开始。在调用函数时,将运行:后面的缩进代码块。
return是与函数唯一关联的另一个关键字。当Python遇到return语句时,它会立即退出函数,并将右侧的值传递给调用上下文。
是否清楚源代码中的最小差异是什么?如果我们不确定,我们可以尝试几个例子:
print(
least_difference(1, 10, 100),
least_difference(1, 10, 10),
least_difference(5, 6, 7), # Python允许在参数列表中使用尾随逗号。那有多好?
)
或者help()函数可以告诉我们一些关于它的信息。
Python不够聪明,无法阅读我的代码并将其转换成一个漂亮的英文描述。但是,当我编写一个函数时,我可以在所谓的docstring中提供一个描述。
文档字符串
def least_difference(a, b, c):
"""Return the smallest difference between any two numbers
among a, b and c.
>>> least_difference(1, 5, -5)
4
"""
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
return min(diff1, diff2, diff3)
docstring是一个三引号的字符串(可以跨多行),紧跟在函数头之后。当我们调用函数的help()时,它会显示docstring。
help(least_difference)
旁白:docstring的最后两行是一个示例函数调用和结果(>>>是对Python交互式shell中使用的命令提示符的引用。)Python不运行示例调用-它只是为了读者的利益。在函数的docstring中包含一个或多个示例调用的约定远未得到普遍遵守,但它可以非常有效地帮助人们理解函数。对于真实世界的示例,请参见numpy函数np.eye的docstring。
优秀的程序员使用docstring,除非他们希望在代码使用后不久就扔掉它(这很少见)。所以,你也应该开始写docstring了!
不返回的函数
如果函数中不包含return关键字会发生什么?
def least_difference(a, b, c):
"""Return the smallest difference between any two numbers
among a, b and c.
"""
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
min(diff1, diff2, diff3)
print(
least_difference(1, 10, 100),
least_difference(1, 10, 10),
least_difference(5, 6, 7),
)
Python允许我们定义这样的函数。调用它们的结果是特殊值None(这类似于其他语言中的“空”概念。)
如果没有return语句,最小的差异是完全没有意义的,但是一个有副作用的函数可以做一些有用的事情而不返回任何东西。我们已经看到了两个这样的例子:print()和help()不返回任何内容。我们只是因为它们的副作用(在屏幕上放一些文字)才给它们打电话。其他有用的副作用示例包括写入文件或修改输入。
mystery = print()
print(mystery)
默认参数
当我们调用help(print)时,我们看到print函数有几个可选参数。例如,我们可以为sep指定一个值,以便在打印的参数之间插入一些特殊的字符串:
print(1, 2, 3, sep=' < ')
但如果不指定值,sep将被视为具有默认值“”(单个空格)。
print(1, 2, 3)
向我们定义的函数添加带有默认值的可选参数非常简单:
def greet(who="Colin"):
print("Hello,", who)
greet()
greet(who="Kaggle")
# (在本例中,我们不需要指定参数的名称,因为它是明确的。)
greet("world")
应用于函数的函数
这是一个强大的东西,虽然一开始感觉很抽象。可以将函数作为参数提供给其他函数。一些例子可以使这一点更清楚:
def mult_by_five(x):
return 5 * x
def call(fn, arg):
"""Call fn on arg"""
return fn(arg)
def squared_call(fn, arg):
"""Call fn on the result of calling fn on arg"""
return fn(fn(arg))
print(
call(mult_by_five, 1),
squared_call(mult_by_five, 1),
sep='\n', # '\n' is the newline character - it starts a new line
)
对其他函数进行操作的函数称为“高阶函数”,您可能暂时不会编写自己的函数。但是Python中内置了一些高阶函数,您可能会发现调用这些函数很有用。
下面是一个使用max函数的有趣示例。
默认情况下,max返回最大的参数。但是,如果我们使用可选的key参数传入函数,它将返回使key(x)最大化的参数x(也称为“argmax”)。
def mod_5(x):
"""Return the remainder of x after dividing by 5"""
return x % 5
print(
'Which number is biggest?',
max(100, 51, 14),
'Which number is the biggest modulo 5?',
max(100, 51, 14, key=mod_5),
sep='\n',
)
三、布尔和条件
布尔值
Python有一种称为bool的变量类型。它有两个可能的值:True和False。
x = True
print(x)
print(type(x))
我们通常从布尔运算符获取布尔值,而不是直接在代码中输入True或False。这些操作员回答是/否问题。我们将通过下面的一些运算符。
比较运算
Operation | Description | Operation | Description | |
---|---|---|---|---|
a == b | a equal to b | a != b | a not equal to b | |
a < b | a less than b | a > b | a greater than b | |
a <= b | a less than or equal to b | a >= b | a greater than or equal to b |
def can_run_for_president(age):
"""Can someone of the given age run for president in the US?"""
# T美国宪法规定你必须至少35岁
return age >= 35
print("Can a 19-year-old run for president?", can_run_for_president(19))
print("Can a 45-year-old run for president?", can_run_for_president(45))
比较经常像你希望的那样起作用
3.0 == 3
但有时也会很棘手
'3' == 3
比较运算符可以与我们已经看到的算术运算符结合起来,以表示几乎无限范围的数学测试。例如,我们可以通过检查带2的模返回1来检查一个数是否为奇数:
def is_odd(n):
return (n % 2) == 1
print("Is 100 odd?", is_odd(100))
print("Is -1 odd?", is_odd(-1))
在进行比较时,请记住使用==而不是=。如果你写n==2,你是在问n的值。当你写n=2时,你正在改变n的值。
组合布尔值
可以使用“and”、“or”和“not”的标准概念组合布尔值。事实上,要做到这一点的话是:和,或,和不是。
有了这些,我们可以使我们的“竞选总统”功能更加准确。
def can_run_for_president(age, is_natural_born_citizen):
"""Can someone of the given age and citizenship status run for president in the US?"""
# 美国宪法规定你必须是天生的公民,至少35岁
return is_natural_born_citizen and (age >= 35)
print(can_run_for_president(19, True))
print(can_run_for_president(55, False))
print(can_run_for_president(55, True))
快,你能猜出这个表达式的值吗?
True or True and False
(点击“输出”按钮查看答案)
要回答这个问题,你需要弄清楚操作的顺序。
例如,和在或之前求值。这就是为什么上面的第一个表达式是正确的。如果我们从左到右计算它,我们会先计算True或True(这是True),然后将结果的and与False相加,得到一个最终值False。
你可以试着记住优先顺序,但更安全的办法是只使用自由括号。这不仅有助于防止bug,还可以让阅读您代码的人更清楚地了解您的意图。
例如,考虑以下表达式:
prepared_for_weather = have_umbrella or rain_level < 5 and have_hood or not rain_level > 0 and is_workday
我想说我不受今天天气的影响。。。。
如果我有伞。。。
或者如果雨不太大,我有个兜帽。。。
否则,我还是没事的,除非下雨而且是工作日
但我的Python代码不仅很难阅读,而且还有一个bug。我们可以通过添加一些括号来解决这两个问题:
prepared_for_weather = have_umbrella or (rain_level < 5 and have_hood) or not (rain_level > 0 and is_workday)
如果您认为有助于提高可读性,可以添加更多括号:
prepared_for_weather = have_umbrella or ((rain_level < 5) and have_hood) or (not (rain_level > 0 and is_workday))
我们还可以将其拆分为多行,以强调上述三部分结构:
prepared_for_weather = (
have_umbrella
or ((rain_level < 5) and have_hood)
or (not (rain_level > 0 and is_workday))
)
条件句
当与条件语句结合使用关键字if、elif和else时,Booleans最有用。
条件语句(通常称为if-then语句)允许您根据某个布尔条件的值来控制要运行的代码段。举个例子:
def inspect(x):
if x == 0:
print(x, "is zero")
elif x > 0:
print(x, "is positive")
elif x < 0:
print(x, "is negative")
else:
print(x, "is unlike anything I've ever seen...")
inspect(0)
inspect(-15)
if和else关键字常用于其他语言;它更独特的关键字是elif,是else if的缩写。在这些条件子句中,elif和else块是可选的;此外,您可以根据需要包含任意多个elif语句。
特别要注意冒号(:)和空格的使用来表示独立的代码块。这类似于我们定义函数时发生的情况-函数头以:,下面的行缩进4个空格。所有随后缩进的行都属于函数体,直到我们遇到一个未缩进的行,结束函数定义。
def f(x):
if x > 0:
print("Only printed when x is positive; x =", x)
print("Also only printed when x is positive; x =", x)
print("Always printed, regardless of x's value; x =", x)
f(1)
f(0)
布尔转换
我们已经看到int(),它将事情转换为ints,float(),这将使事情变成float,因此您可能不会惊讶地听到Python有一个bool()函数,它将事情变成bools。
print(bool(1)) # 除0外,所有数字均视为真
print(bool(0))
print(bool("asf")) # 除空字符串外,所有字符串都被视为true
print(bool(""))
# 通常为空序列(字符串、列表和其他类型,如列表和元组)
# 是 "falsey",其余的是 "truthy"
我们可以在if条件和其他需要布尔值的地方使用非布尔对象。Python会隐式地将它们视为对应的布尔值:
if 0:
print(0)
elif "spam":
print("spam")
四、列表
列表
Python中的列表表示值的有序序列。下面是如何创建它们的示例:
primes = [2, 3, 5, 7]
我们可以在列表中列出其他类型的内容:
planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
我们甚至可以列一个清单:
hands = [
['J', 'Q', 'K'],
['2', '2', '2'],
['6', 'A', 'K'], # (Comma after the last element is optional)
]
# (我也可以把这个写在一行上,但读起来很难)
hands = [['J', 'Q', 'K'], ['2', '2', '2'], ['6', 'A', 'K']]
列表可以包含不同类型变量的组合:
my_favourite_things = [32, 'raindrops on roses', help]
# (是的,Python的帮助函数肯定是我最喜欢的东西之一)
索引
可以使用方括号访问各个列表元素。
哪颗行星离太阳最近?Python使用基于零的索引,因此第一个元素的索引为0。
planets[0]
哪颗行星离太阳最远?
可以使用负数访问列表末尾的元素,从-1开始:
planets[-1]
planets[-2]
'Neptune'
'Uranus'
切片
前三颗行星是什么?我们可以通过切片来回答这个问题:
planets[0:3]
['Mercury', 'Venus', 'Earth']
行星[0:3]是我们求行星元素的方法,从索引0开始,一直到索引3,但不包括索引3。
起始索引和结束索引都是可选的。如果省略起始索引,则假定为0。因此可以将上面的表达式重写为:
planets[:3]
['Mercury', 'Venus', 'Earth']
如果省略了结束索引,则假定它是列表的长度
planets[3:]
['Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
上面的表达意思是“给我从索引3开始的所有行星”。
我们也可以在切片时使用负索引:
# 所有的行星除了第一个和最后一个
planets[1:-1]
['Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus']
# 最后三颗行星
planets[-3:]
['Saturn', 'Uranus', 'Neptune']
更改列表
列表是“可变的”,这意味着它们可以“就地”修改。
修改列表的一种方法是为索引或切片表达式赋值。
例如,假设我们要重命名Mars:
planets[3] = 'Malacandra'
planets
['Mercury', 'Venus', 'Earth', 'Malacandra', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
嗯,真是太多了。让我们通过缩短前三颗行星的名字来补偿。
planets[:3] = ['Mur', 'Vee', 'Ur']
print(planets)
# 那太傻了。让我们把他们的旧名字还给他们
planets[:4] = ['Mercury', 'Venus', 'Earth', 'Mars',]
['Mur', 'Vee', 'Ur', 'Malacandra', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
列表函数
Python有几个有用的函数用于处理列表。
len给出了列表的长度:
# 有多少颗行星?
len(planets)
8
排序返回列表的排序版本:
# 行星按字母顺序排列
sorted(planets)
['Earth', 'Jupiter', 'Mars', 'Mercury', 'Neptune', 'Saturn', 'Uranus', 'Venus']
sum实现了您可能期望的:
primes = [2, 3, 5, 7]
sum(primes)
17
我们以前使用过min和max来获得几个参数的最小值或最大值。但我们也可以传入一个list参数。
max(primes)
7
插曲:对象
到目前为止,我已经使用了很多术语“object”——您可能已经读到Python中的所有东西都是对象。那是什么意思?
简而言之,物体随身携带着一些东西。您可以使用Python的点语法访问这些内容。
例如,Python中的数字携带一个称为imag的相关变量,该变量表示它们的虚部(你可能永远都不需要使用这个,除非你在做一些非常奇怪的数学。)
x = 12
# x是实数,所以它的虚部是0。
print(x.imag)
# 以下是如何制作一个复数,以防你好奇:
c = 12 + 3j
print(c.imag)
0 3.0
物体所携带的东西也可以包含函数。附加到对象的函数称为方法(附加到对象上的非函数对象(如imag)称为属性(attributes)。
例如,数字有一个名为bit\ u length的方法。同样,我们使用点语法访问它:
x.bit_length
<function int.bit_length()>
实际上,我们加上括号:
x.bit_length()
4
旁白:如果你在做练习的话,你实际上已经在调用方法了。在练习中,笔记本q1、q2、q3等都是具有名为check、hint和solution的方法的对象。
与我们可以将函数传递给help函数(例如help(max))的方式相同,我们还可以传递方法:
help(x.bit_length)
上面的例子完全不清楚。到目前为止,我们所研究的对象类型(数字、函数、布尔值)中没有一种具有您可能使用过的属性或方法。
但事实证明,列表有几种方法,你会一直使用。
列表方法
list.append通过在末尾添加项来修改列表:
# 冥王星是个该死的星球!
planets.append('Pluto')
旁白:append是一种由类型列表中的所有对象(不仅仅是行星)携带的方法,因此我们也可以调用help(list.append)。然而,如果我们试图调用help(append),Python将抱怨没有名为“append”的变量。“append”名称仅存在于列表中—它不存在于独立名称中,例如max或len等内置函数。
help(planets.append)
->None部分告诉我们list.append不返回任何内容。但是如果我们检查行星的值,我们可以看到方法调用修改了行星的值:
planets
['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto']
list.pop删除并返回列表的最后一个元素:
planets.pop()
'Pluto'
planets
['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
搜索列表
地球是在什么地方按行星的顺序下降的?我们可以使用list.index方法获取它的索引。
planets.index('Earth')
2
它排在第三位(即索引2-0)。
冥王星以什么指数出现?
planets.index('Pluto')
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-30-3a8584cba91a> in <module> ----> 1 planets.index('Pluto') ValueError: 'Pluto' is not in list
哦,没错。。。
为了避免这样令人不快的意外,我们可以使用in运算符来确定列表是否包含特定值:
# 地球是行星吗?
"Earth" in planets
True
# Calbefraques是行星吗?
"Calbefraques" in planets
False
还有一些更有趣的列表方法我们还没有涉及。如果您想了解附加到特定对象的所有方法和属性,我们可以调用对象本身的help()。例如,help(planets)将告诉我们所有列表方法:
help(planets)
单击“输出”按钮查看完整的帮助页。列表中有很多方法的名字很奇怪,比如eq和iadd。现在不要太担心这些(您可能永远不会直接调用这些方法。但当我们使用索引或比较运算符等语法时,它们会在幕后被调用。)最有趣的方法是在列表的底部(append、clear、copy等)。
多元组
元组与列表几乎完全相同。它们只有两个不同之处。
1:创建它们的语法使用括号而不是方括号
t = (1, 2, 3)
t = 1, 2, 3 # 相当于上述
t
(1, 2, 3)
2:不能修改(不可变)。
元组通常用于具有多个返回值的函数。
例如,float对象的as\u integer\u ratio()方法返回元组形式的分子和分母:
x = 0.125
x.as_integer_ratio()
(1, 8)
这些多个返回值可以单独指定如下:
numerator, denominator = x.as_integer_ratio()
print(numerator / denominator)
0.125
最后,我们对经典的愚蠢的蟒蛇把戏有了一些了解™ 交换两个变量!
a = 1
b = 0
a, b = b, a
print(a, b)
0 1
五、循环和列表理解
循环
循环是重复执行某些代码的一种方式。举个例子:
planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
for planet in planets:
print(planet, end=' ') # print all on same line
Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune
for循环指定
要使用的变量名(在本例中为planet)
要循环的一组值(在本例中为行星)
你用“in”这个词把它们联系在一起。
“in”右边的对象可以是任何支持迭代的对象。基本上,如果它可以被认为是一组东西,你可以循环它。除了列表,我们还可以迭代元组的元素:
multiplicands = (2, 2, 2, 3, 3, 5)
product = 1
for mult in multiplicands:
product = product * mult
product
360
您甚至可以循环遍历字符串中的每个字符:
s = 'steganograpHy is the practicE of conceaLing a file, message, image, or video within another fiLe, message, image, Or video.'
msg = ''
# 一次打印一个大写字母
for char in s:
if char.isupper():
print(char, end='')
HELLO
range()
range()是一个返回数字序列的函数。它对于编写循环非常有用。
例如,如果我们想将某个动作重复5次:
for i in range(5):
print("Doing important work. i =", i)
Doing important work. i = 0 Doing important work. i = 1 Doing important work. i = 2 Doing important work. i = 3 Doing important work. i = 4
while循环
Python中的另一种类型的循环是while循环,它不断迭代,直到满足某些条件:
i = 0
while i < 10:
print(i, end=' ')
i += 1 # increase the value of i by 1
0 1 2 3 4 5 6 7 8 9
while循环的参数将作为布尔语句进行计算,循环将一直执行,直到语句的计算结果为False。
列表解析
列表理解是Python最受欢迎和最独特的特性之一。理解它们最简单的方法可能就是看几个例子:
squares = [n**2 for n in range(10)]
squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
下面是我们如何在没有列表理解的情况下做同样的事情:
squares = []
for n in range(10):
squares.append(n**2)
squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
我们还可以添加if条件:
short_planets = [planet for planet in planets if len(planet) < 6]
short_planets
['Venus', 'Earth', 'Mars']
(如果您熟悉SQL,您可能会认为这就像一个“WHERE”子句)
下面是一个使用if条件过滤并对循环变量应用某种转换的示例:
# str.upper() 返回字符串的全大写版本
loud_short_planets = [planet.upper() + '!' for planet in planets if len(planet) < 6]
loud_short_planets
['VENUS!', 'EARTH!', 'MARS!']
人们通常把这些写在一行上,但如果把它们分成三行,你会发现结构更清晰:
[
planet.upper() + '!'
for planet in planets
if len(planet) < 6
]
['VENUS!', 'EARTH!', 'MARS!']
(继续SQL类比,您可以将这三行看作SELECT、FROM和WHERE)
左边的表达式在技术上不必包含循环变量(尽管不包含循环变量是很不寻常的)。你认为下面的表达式的计算结果是什么?按“输出”按钮进行检查。
[32 for planet in planets]
[32, 32, 32, 32, 32, 32, 32, 32]
列表理解与min、max和sum等函数相结合,可以为需要几行代码的问题提供令人印象深刻的单行解决方案。
例如,比较执行相同操作的以下两个代码单元。
def count_negatives(nums):
"""Return the number of negative numbers in the given list.
>>> count_negatives([5, -1, -2, 0, 3])
2
"""
n_negative = 0
for num in nums:
if num < 0:
n_negative = n_negative + 1
return n_negative
下面是一个使用列表理解的解决方案:
def count_negatives(nums):
return len([num for num in nums if num < 0])
好多了,对吧?
如果我们所关心的只是最小化代码的长度,那么第三种解决方案更好!
def count_negatives(nums):
return sum([num < 0 for num in nums])
这些解决方案中哪一个是“最好的”完全是主观的。用更少的代码解决问题总是很好的,但是值得记住的是Python的禅宗中的以下几行:
可读性很重要。
显性比隐性好。
所以,使用这些工具来制作紧凑可读的程序。但是当你不得不选择的时候,你应该选择那些别人容易理解的代码。
六、字符串和字典
字符串
Python语言真正闪耀的地方之一是字符串的操作。本节将介绍Python的一些内置字符串方法和格式化操作。
这种字符串操作模式经常出现在数据科学工作的上下文中。
字符串语法
在前面的课程中,您已经在示例中看到了大量的字符串,但是简单回顾一下,Python中的字符串可以使用单引号或双引号来定义。它们在功能上是等价的。
x = 'Pluto is a planet'
y = "Pluto is a planet"
x == y
True
如果字符串包含一个引号字符(例如,表示撇号),则双引号非常方便。
同样,如果将其包装为单引号,那么创建包含双引号的字符串也很容易:
print("Pluto's a planet!")
print('My dog is named "Pluto"')
Pluto's a planet! My dog is named "Pluto"
如果我们试图将单引号字符放在单引号字符串中,Python会感到困惑:
'Pluto's a planet!'
File "<ipython-input-3-a43631749f52>", line 1 'Pluto's a planet!' ^ SyntaxError: invalid syntax
我们可以通过用反斜杠“转义”单引号来解决这个问题。
'Pluto\'s a planet!'
"Pluto's a planet!"
下表总结了反斜杠字符的一些重要用法。
What you type... | What you get | example | print(example) |
---|---|---|---|
\' | ' | 'What\'s up?' | What's up? |
\" | " | "That's \"cool\"" | That's "cool" |
\\ | \ | "Look, a mountain: /\\" | Look, a mountain: /\ |
\n | "1\n2 3" | 1 2 3 |
最后一个序列,\n表示换行符。它使Python开始新的一行。
hello = "hello\nworld"
print(hello)
此外,Python的字符串三重引号语法允许我们按字面意思包含换行符(即,只需在键盘上按回车键,而不是使用特殊的“\n”序列)。我们已经在用于记录函数的docstring中看到了这一点,但是我们可以在任何需要定义字符串的地方使用它们。
triplequoted_hello = """hello
world"""
print(triplequoted_hello)
triplequoted_hello == hello
hello world
True
print()函数会自动添加换行符,除非我们为关键字参数end指定的值不是默认值'\n':
print("hello")
print("world")
print("hello", end='')
print("pluto", end='')
hello world hellopluto
字符串是序列
字符串可以看作是字符序列。几乎我们看到的所有事情,我们都可以做一个列表,我们也可以做一个字符串。
planet = 'Pluto'
planet[0]
'P'
planet[-3:]
'uto'
len(planet)
5
[char+'! ' for char in planet]
['P! ', 'l! ', 'u! ', 't! ', 'o! ']
但它们不同于列表的一个主要方面是它们是不变的。我们不能修改它们。
planet[0] = 'B'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-12-6ca42463b9f9> in <module> ----> 1 planet[0] = 'B' 2 # planet.append doesn't work either TypeError: 'str' object does not support item assignment
字符串方法
与list类似,str类型有很多非常有用的方法。这里我只举几个例子。