Python实用技巧与数据处理
1. 开始使用Python
在完成Python的基础设置后,就可以在计算机上运行Python代码了。如果你是Python新手,接下来需要学习一些语言特性。Python是最简单、最易学习的编程语言之一,网上有许多优秀的资源和书籍可帮助你学习Python编程基础,python.org是个很好的起点。
2. Python中的数字与数学运算
Python和大多数语言一样,内置了对基本数学运算的支持。下面为你介绍一些常见的运算操作。
2.1 基本算术运算符
Python中的基本算术运算符包括
+
、
-
、
*
和
/
。需要注意的是,在Python 3中进行整数除法时,可能会得到小数结果,例如:
>>> 7/2
3.5
而在Python 2中,上述运算结果为2,即直接舍弃余数的整数除法结果。若需要获取余数,可以使用
%
运算符,也就是取模运算符。例如:
>>> 13 % 5
3
这表明13除以5的余数是3(即13 = 2 × 5 + 3)。取模运算符同样适用于浮点数,例如可以用它来获取一个数的小数部分:
>>> 3.75 % 1
0.75
除了上述四个基本运算符外,
**
运算符用于计算幂次方。例如:
>>> 2 ** 3
8
>>> 4 ** 2
16
在Python中进行浮点数运算时,结果可能并不精确。例如:
>>> 1000.1 - 1000.0
0.10000000000002274
虽然这个结果与正确答案的误差在万亿分之一以内,不会引发问题,但乍一看可能会让人觉得结果有误。例如:
>>> (1000.1 - 1000.0) - 0.1
2.273181642920008e-14
这个长数字采用科学记数法表示,约为2.27 × 10⁻¹⁴,实际上非常接近零。
2.2 math模块
Python的
math
模块提供了更多有用的数学常量和函数。使用时,需要从该模块中导入所需的对象。例如,导入圆周率
pi
:
from math import pi
>>> pi
3.141592653589793
>>> tau = 2 * pi
>>> tau
6.283185307179586
也可以直接导入
math
模块,然后按需访问其中的值:
>>> import math
>>> math.pi
3.141592653589793
>>> math.e
2.718281828459045
math
模块还包含一些重要的函数,如平方根函数
sqrt
、三角函数
cos
和
sin
、指数函数
exp
以及自然对数函数
log
等。调用这些函数时,需在括号内提供输入值:
>>> math.sqrt(25)
5.0
>>> math.sin(pi/2)
1.0
>>> math.cos(pi/3)
0.5000000000000001
>>> math.exp(2)
7.38905609893065
>>> math.log(math.exp(2))
2.0
需要注意的是,
math.exp(x)
等同于
math.e ** x
,而
math.log
函数则是
math.exp
函数的逆运算。三角函数在相关章节有详细介绍。
2.3 随机数
有时我们需要选择一些任意数字来测试计算结果,这时可以使用Python的随机数生成器。这些生成器位于
random
模块中,使用前需先导入:
import random
该模块中的
randint
函数可返回指定范围内随机选取的整数,例如:
>>> random.randint(0,10)
7
>>> random.randint(0,10)
1
random.uniform
函数用于生成指定区间内的随机浮点数。例如:
>>> random.uniform(7.5, 9.5)
8.200084576283352
“uniform”表示该区间内的每个子区间被选中的概率相同。与之相反,如果随机选取人的年龄,得到的随机数分布是不均匀的,例如10 - 20岁的人数可能会比100 - 110岁的人数多很多。
3. Python中的数据集合
在Python中,有多种方式来处理数据集合,下面为你详细介绍。
3.1 列表
列表是Python中最基本的数据集合。创建列表时,只需将一些值用方括号括起来,并用逗号分隔。例如:
months = ["January", "February", "March"]
可以通过索引(从0开始计数)来访问列表中的元素。例如:
>>> months[0]
'January'
>>> months[1]
'February'
>>> months[2]
'March'
若尝试访问超出有效索引范围的元素,会引发错误。例如,
months[3]
或
months[17]
是不存在的。在某些情况下,可以使用取模运算符来确保索引的有效性,例如对于任意整数
n
,
months[n % 3]
总是有效的,因为
n % 3
的结果只能是0、1或2。
还可以通过解包的方式来访问列表元素。如果确定列表中有三个元素,可以这样操作:
j, f, m = months
>>> j
'January'
>>> f
'February'
>>> m
'March'
列表的另一个基本操作是拼接,使用
+
运算符可以将两个列表按顺序合并成一个更大的列表。例如:
>>> [1,2,3] + [4,5,6]
[1, 2, 3, 4, 5, 6]
Python还支持列表切片操作,用于提取列表中两个索引之间的所有元素。例如:
>>> months[1:3]
['February', 'March']
上述代码表示从索引1开始,到索引3(不包含)结束的切片。再看一个更清晰的例子:
>>> nums = [0,1,2,3,4,5,6,7,8,9,10]
>>> nums[2:5]
[2, 3, 4]
可以使用
len
函数来计算列表的长度:
>>> len(months)
3
>>> len(nums)
11
由于列表索引从0开始,因此最后一个元素的索引为列表长度减1。可以通过以下两种方式获取列表的最后一个元素:
>>> nums[len(nums)-1]
10
>>> nums[-1]
10
nums[-2]
则返回倒数第二个元素,即9。正索引、负索引和切片可以有多种组合方式。例如:
>>> nums[1:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> nums[3:-1]
[3, 4, 5, 6, 7, 8, 9]
需要注意的是,不要将列表切片语法(涉及两个索引)与从嵌套列表中获取元素(也涉及两个索引)混淆。例如:
list_of_lists = [[1,2,3],[4,5,6],[7,8,9]]
>>> list_of_lists[2][1]
8
在处理列表时,经常需要遍历列表中的每个元素。在Python中,最简便的方法是使用
for
循环。例如:
>>> for x in months:
>>> print('Month: ' + x)
Month: January
Month: February
Month: March
也可以通过创建一个空列表,然后使用
append
方法逐步添加元素来构建新列表。例如:
squares = []
for n in nums:
squares.append(n * n)
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Python还提供了列表推导式这一特殊语法,用于迭代构建列表。它本质上是一种特殊的
for
循环,用方括号括起来,表示在迭代的每一步添加列表元素。列表推导式的语法类似于自然语言,易于理解。例如:
>>> [x * x for x in nums]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表推导式还可以同时遍历多个源列表。例如:
>>> years = [2018,2019,2020]
>>> [m + " " + str(y) for y in years for m in months]
['January 2018',
'February 2018',
'March 2018',
'January 2019',
'February 2019',
'March 2019',
'January 2020',
'February 2020',
'March 2020']
通过嵌套列表推导式,可以构建列表的列表:
>>> [[m + " " + str(y) for y in years] for m in months]
[['January 2018', 'January 2019', 'January 2020'],
['February 2018', 'February 2019', 'February 2020'],
['March 2018', 'March 2019', 'March 2020']]
3.2 其他可迭代对象
在Python(尤其是Python 3.x)中,还有一些其他类型的集合,其中一些被称为可迭代对象,因为可以像遍历列表一样遍历它们。最常用的可迭代对象之一是
range
,用于构建有序的数字序列。例如:
>>> range(5,10)
range(5, 10)
虽然直接计算
range(5,10)
的结果看起来并不直观,但可以像遍历列表一样遍历它:
>>> for i in range(5,10):
>>> print(i)
5
6
7
8
9
range
不是列表,这使得我们可以使用非常大的范围而无需一次性迭代所有元素。例如,
range(0,1000000000)
定义了一个包含十亿个数字的范围,但实际上并不存储十亿个数字,只是存储了在迭代过程中生成这些数字的指令。如果需要将
range
转换为列表,可以使用
list
函数:
>>> list(range(0,10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range
函数的部分参数是可选的。如果只提供一个输入,它会自动从0开始,直到该输入数字;如果提供第三个参数,则表示步长。例如:
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(0,10,3))
[0, 3, 6, 9]
zip
函数也是一个返回特殊可迭代对象的例子。它接受两个长度相同的可迭代对象,并返回一个由对应元素组成的可迭代对象:
>>> z = zip([1,2,3],["a","b","c"])
>>> z
<zip at 0x15fa8104bc8>
>>> list(z)
[(1, 'a'), (2, 'b'), (3, 'c')]
需要注意的是,并非所有可迭代对象都支持索引操作。例如,
z[2]
是无效的,需要先将其转换为列表,如
list(z)[2]
。
range
支持索引操作,例如
range(5,10)[3]
返回8。另外,一旦遍历了
zip
对象,它就不再存在了,因此如果需要重复使用,最好立即将其转换为列表。
下面是一个简单的流程图,展示了可迭代对象的使用流程:
graph TD;
A[定义可迭代对象] --> B{是否为range};
B -- 是 --> C[可直接遍历或转换为列表];
B -- 否 --> D{是否为zip};
D -- 是 --> E[转换为列表后使用];
D -- 否 --> F[按常规方式处理];
3.3 生成器
Python的生成器提供了一种创建可迭代对象的方式,它不会一次性存储所有值,而是存储生成值的指令。这使得我们可以定义大型甚至无限的序列,而无需将它们全部存储在内存中。生成器的基本创建方式类似于函数,但使用
yield
关键字代替
return
。生成器可以产生多个值,而函数最多返回一次就结束了。
例如,以下生成器表示从0开始的无限整数序列:
def count():
x = 0
while True:
yield x
x += 1
虽然这表示一个无限序列,但调用
count()
不会导致计算机崩溃,它只是返回一个生成器对象:
>>> count()
<generator object count at 0x0000015FA80EC750>
for x in count()
这样的循环是有效的,但会无限运行。可以使用
break
语句来终止循环:
for x in count():
if x > 1000:
break
else:
print(x)
下面是一个更实用的生成器,它类似于
range
函数,只生成有限个值:
def count(a,b):
x = a
while x < b:
yield x
x += 1
count(10,20)
的结果是一个类似于
range(10,20)
的生成器,可以在列表推导式中使用:
>>> count(10,20)
<generator object count at 0x0000015FA80EC9A8>
>>> [x for x in count(10,20)]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
可以通过将列表推导式的方括号替换为圆括号来创建生成器表达式。例如:
(x*x for x in range(0,10))
它的行为与以下生成器相同:
def squares():
for x in range(0,10):
yield x*x
当生成器是有限的时,可以使用
list
函数将其安全地转换为列表:
>>> list(squares())
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3.4 元组
元组是一种类似于列表的可迭代对象,但它是不可变的,即创建后不能修改。这意味着元组没有
append
方法,一旦创建,其长度就固定不变。元组适用于存储成对或成组的数据。创建元组的方式与列表类似,只是使用括号(或不使用任何括号)代替方括号:
>>> (1,2)
(1, 2)
>>> ("a","b","c")
('a', 'b', 'c')
>>> 1,2,3,4,5
(1, 2, 3, 4, 5)
在前面提到的
zip
函数返回的结果中,每个元素实际上就是一个元组。在某种意义上,元组是Python中的默认集合。例如:
a = 1,2,3,4,5
此时
a
会自动被解释为一个包含这些数字的元组。同样,如果函数以
return a,b
结束,实际返回的是元组
(a,b)
。
由于元组通常较短,通常不需要遍历它们。虽然没有元组推导式,但可以在其他推导式中遍历元组,并使用内置的
tuple
函数将结果转换回元组。例如:
>>> a = 1,2,3,4,5
>>> tuple(x + 10 for x in a)
(11, 12, 13, 14, 15)
3.5 集合
Python集合中的每个元素必须是唯一的,并且不记录元素的顺序。在某些情况下,将列表转换为集合是确保列表中没有重复值的快速方法。可以使用
set
函数将可迭代对象转换为集合:
>>> dups = [1,2,3,3,3,3,4,5,6,6,6,6,7,8,9,9,9]
>>> set(dups)
{1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> list(set(dups))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Python集合使用花括号表示,这与数学中的集合表示方法相同。可以直接使用花括号定义集合。由于集合不考虑顺序,只要两个集合的元素完全相同,它们就相等:
>>> set([1,1,2,2,3]) == {3,2,1}
True
以下是一个表格,总结了各种数据集合的特点:
| 数据集合类型 | 是否可变 | 是否有序 | 是否允许重复元素 | 常用操作 |
| ---- | ---- | ---- | ---- | ---- |
| 列表 | 是 | 是 | 是 | 索引、切片、拼接、遍历、列表推导式 |
| 元组 | 否 | 是 | 是 | 索引、解包、遍历 |
| 集合 | 是 | 否 | 否 | 去重、判断元素是否存在 |
| 生成器 | 无 | 无 | 无 | 迭代生成值 |
| range | 无 | 是 | 无 | 生成连续整数序列 |
| zip | 无 | 是 | 无 | 组合多个可迭代对象 |
通过以上介绍,你对Python中的数字运算、数据集合等方面有了更深入的了解。在实际编程中,可以根据具体需求选择合适的数据结构和操作方法,以提高代码的效率和可读性。
Python实用技巧与数据处理
4. NumPy数组
除了Python内置的数据集合外,NumPy数组也是一种常用的数据集合,它来自NumPy包,是Python中事实上的标准数值计算库。NumPy数组在处理大规模数值数据时具有高效性,并且提供了许多方便的数学运算和操作。
以下是一个简单的NumPy数组创建示例:
import numpy as np
# 创建一个一维数组
arr1 = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr1)
# 创建一个二维数组
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("二维数组:", arr2)
NumPy数组的索引和切片操作与列表类似,但更加灵活和强大。例如:
# 一维数组索引
print("一维数组索引:", arr1[2])
# 二维数组索引
print("二维数组索引:", arr2[1, 2])
# 一维数组切片
print("一维数组切片:", arr1[1:4])
# 二维数组切片
print("二维数组切片:", arr2[:, 1:])
NumPy数组还支持各种数学运算,这些运算可以直接应用于整个数组,而无需使用循环。例如:
# 数组加法
arr3 = arr1 + 10
print("数组加法:", arr3)
# 数组乘法
arr4 = arr1 * 2
print("数组乘法:", arr4)
# 数组之间的运算
arr5 = arr1 + arr3
print("数组之间的加法:", arr5)
NumPy还提供了许多用于数组操作的函数,如求和、求平均值、求最大值等。例如:
# 数组求和
sum_arr = np.sum(arr1)
print("数组求和:", sum_arr)
# 数组求平均值
mean_arr = np.mean(arr1)
print("数组求平均值:", mean_arr)
# 数组求最大值
max_arr = np.max(arr1)
print("数组求最大值:", max_arr)
下面是一个流程图,展示了使用NumPy数组进行数据处理的基本流程:
graph TD;
A[导入NumPy库] --> B[创建NumPy数组];
B --> C{选择操作类型};
C -- 索引/切片 --> D[进行索引或切片操作];
C -- 数学运算 --> E[进行数组数学运算];
C -- 统计计算 --> F[进行统计计算];
D --> G[输出结果];
E --> G;
F --> G;
5. 综合应用示例
为了更好地理解和应用上述Python知识,下面给出一个综合应用示例。假设我们要模拟一个简单的抽奖活动,参与者的编号从1到100,我们需要随机抽取5名幸运参与者。
import random
# 生成参与者编号列表
participants = list(range(1, 101))
# 随机抽取5名幸运参与者
lucky_participants = random.sample(participants, 5)
print("幸运参与者编号:", lucky_participants)
在这个示例中,我们首先使用
range
函数生成了一个从1到100的参与者编号列表,然后使用
random.sample
函数从这个列表中随机抽取了5个不重复的元素作为幸运参与者的编号。
6. 总结与建议
通过前面的介绍,我们对Python中的数字运算、数据集合(包括列表、元组、集合、生成器、range、zip和NumPy数组)等方面有了全面的了解。在实际编程中,我们可以根据不同的需求选择合适的数据结构和操作方法。
以下是一些总结和建议:
-
选择合适的数据结构
:
- 如果需要频繁修改元素,列表是一个不错的选择。
- 如果数据是不可变的,并且需要保持顺序,元组更合适。
- 如果需要去重,集合是首选。
- 对于大规模数值计算,NumPy数组具有高效性。
- 如果需要生成大型或无限序列,生成器是一个很好的解决方案。
-
合理使用数学运算和函数
:
- 利用Python内置的数学运算符和
math
模块进行基本数学运算。
- 使用
random
模块生成随机数进行测试或模拟。
- 借助NumPy库的函数进行高效的数值计算和统计分析。
-
提高代码可读性和效率
:
- 使用列表推导式、生成器表达式等简洁的语法来构建列表和生成器。
- 避免不必要的循环,利用数组的向量化运算提高代码效率。
通过不断练习和实践,你将更加熟练地掌握这些Python技巧和数据处理方法,从而编写出更加高效、简洁和易读的代码。
希望这些内容对你学习和使用Python有所帮助,祝你在编程的道路上取得更多的进步!
超级会员免费看
1763

被折叠的 条评论
为什么被折叠?



