Python入门之函数、列表与元组核心用法(附实战案例)
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">前言:</a></li><li><a href="#_label1">一. 函数:告别重复代码的 “代码工厂”</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_0">1.1 为什么需要函数?</a></li><li><a href="#_lab2_1_1">1.2 函数的核心语法(重点)</a></li><li><a href="#_lab2_1_2">1.3 函数的进阶用法(嵌套 + 递归)</a></li><li><a href="#_lab2_1_3">1.4 函数核心小结</a></li></ul><li><a href="#_label2">二. 列表和元组:批量存储数据的 “容器”</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_4">2.1 列表(list):最常用的可变容器</a></li><li><a href="#_lab2_2_5">2.2 元组(tuple):不可变的序列容器</a></li><li><a href="#_lab2_2_6">2.3 列表的元组小结</a></li></ul><li><a href="#_label3">结尾:</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>前言:</h2><blockquote><p>作为 Python 初学者,掌握<strong>函数</strong>、<strong>列表</strong>、<strong>元组</strong>是从 “写代码” 到 “写好代码” 的关键一步。它们不仅是 Python 语法的核心,更是后续处理复杂数据、构建高效程序的基础。今天这篇文章,就结合入门实战案例,把这三个知识点讲透,新手也能一看就会、一用就通。</p></blockquote>
<p class="maodian"><a name="_label1"></a></p><h2>一. 函数:告别重复代码的 “代码工厂”</h2>
<p class="maodian"><a name="_lab2_1_0"></a></p><h3>1.1 为什么需要函数?</h3>
<p>写代码最忌讳的就是 <strong>“复制粘贴”</strong>。比如计算不同区间的数列和(1-100、300-400、1-1000),如果不使用函数,需要重复写多组几乎一样的循环代码:</p>
<div class="jb51code"><pre class="brush:py;"># 1. 计算 1-100 的和
theSum = 0
for i in range(1,101):
theSum = theSum + i
print(theSum)
# 2. 计算 300-400 的求和
theSum = 0
for i in range(300,401):
theSum = theSum + i
print(theSum)
# 计算 1-1000 的和
theSum = 0
for i in range(1,1001):
theSum = theSum + i
print(theSum)
</pre></div>
<p>一旦需要修改计算逻辑(比如改成求平方和),所有重复代码都要改,效率极低。而函数的核心作用,就是<strong>提取重复代码,实现代码复用</strong>,让程序更简洁、更好维护。</p>
<p><strong>简单理解</strong>:函数就像一个 “工厂”,输入 “原材料”(参数),经过内部加工(函数体),输出 “产品”(返回值),一次定义,多次调用。</p>
<p><strong>函数版本代码</strong>:</p>
<div class="jb51code"><pre class="brush:py;"># 使用函数的方式来解决刚刚的问题
# 定义一个求和函数
def calcSum(begin,end):
theSum = 0
for i in range(begin,end+1):
theSum = theSum + i
print(theSum)
# 使用函数
# 求 1-100 的和
calcSum(1,100)
# 求 300-400 的和
calcSum(300,400)
# 求 1-1000 的和
calcSum(1,1000)
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011109331290.png" /></p>
<p class="maodian"><a name="_lab2_1_1"></a></p><h3>1.2 函数的核心语法(重点)</h3>
<p><strong>(1)函数定义与调用</strong></p>
<div class="jb51code"><pre class="brush:py;"># 1. 定义函数:def 函数名(形参列表): 函数体 return 返回值
def calcsum(beg, end):# beg、end是“形式参数”(形参),相当于工厂的“原材料入口”
sum = 0
for i in range(beg, end + 1):
sum += i
return sum# return 输出结果,相当于工厂的“产品出口”
# 2. 调用函数:函数名(实参列表)
result1 = calcsum(1, 100)# 1、100是“实际参数”(实参),是真正传入的原材料
result2 = calcsum(300, 400)
print(result1, result2)# 输出:5050 35150
</pre></div>
<div class="jb51code"><pre class="brush:py;">def test(a,b,c):
print(a,b,c)
# 实参个数不能多也不能少,除非形参有默认参数
test(10,20,30)
</pre></div>
<p><strong>⚠️ 关键注意点</strong>:</p>
<ul><li>函数<strong>必须先定义,再调用</strong>(就像动漫里“先喊招式名,再释放技能”),否则会报 <code>NameError</code>;</li><li>定义函数时不会执行函数体,只要调用时才会执行,调用几次就执行几次;</li><li>形参和实参的<strong>个数必须匹配</strong>(比如定义时 2 个形参,调用时就必须传 2 个实参),否则报 <code>TypeError</code>;</li></ul>
<p><strong>(2) 函数参数的灵活用法</strong><br />Python 的函数参数比C++,Java更灵活,核心有 3 个特性:</p>
<p><strong>1. 动态类型:形参无需指定类型,一个函数可接收多种类型参数</strong></p>
<div class="jb51code"><pre class="brush:py;">def print_param(a):
print(a)
print_param(10) # 整数
print_param("hello")# 字符串
print_param(True) # 布尔值(均能正常执行)
</pre></div>
<div class="jb51code"><pre class="brush:py;">def add(x,y):
return x+y
print(add(10,20))
print(add(1.5,2.5))
print(add('hello','world'))
# # 这个就肯定不行了.不符合函数体内执行逻辑
# print(add(10,'hello'))
</pre></div>
<p><strong>2. 参数默认值:给形参指针默认值,调用时可省略该参数(默认值参数必须在无默认值参数后面)</strong></p>
<div class="jb51code"><pre class="brush:py;"># 计算两数之和,默认不打印调试信息
def add(x, y, debug=False):
if debug:
print(f"调试:x={x}, y={y}")
return x + y
print(add(10, 20)) # 省略debug,使用默认值False
print(add(10, 20, True))# 显式传参,打印调试信息
</pre></div>
<p><strong>3. 关键字参数:调用时显示指定“实参对应哪个形参”,可打乱传参顺序</strong></p>
<div class="jb51code"><pre class="brush:py;">def test(x,y):
print(f"x = {x}")
print(f"y = {y}")
# 关键字参数,顺序无关,输出: x = 10,y = 20;
test(x = 10,y = 20)
test(y = 100,x = 200)
test(100,y = 200)
# 这样写就不行了
# test(x = 100,200)
</pre></div>
<p><strong>(3) 函数返回值</strong></p>
<p>返回值是函数的 “输出”,核心用法有两点:</p>
<p><strong>1. 一个函数可以有多个 return 语句,执行到 return 时函数立刻结束(后续代码不执行)</strong></p>
<div class="jb51code"><pre class="brush:py;"># 这种情况不算是有多个 return 语句
# def tes():
# return 1
# return 2
# 一般情况下多个 return 语句是搭配 分支语句/循环语句 的
# 用来判断 num 是不是奇数
def isOdd(num):
if num % 2 == 0:
return False
else:
return True
print(isOdd(10))
print(isOdd(19))
</pre></div>
<p><strong>2. 一次返回多个值:用逗号分隔,接收时用多个变量接收(无需接收的用 _ 忽略)</strong></p>
<div class="jb51code"><pre class="brush:py;"># 写一个函数, 返回平面上的一个点
# 横坐标,纵坐标
def getPoint():
x = 10
y = 20
return x,y
# 可以返回两个值
# a,b = getPoint()# 接收所有返回值
# 如果只想用其中一个可以使用 _ 占位
# _,b=getPoint() # 忽略x,只接收y
</pre></div>
<p><strong>(4) 变量作用域</strong></p>
<p>变量的作用域决定了 “变量能在哪些地方使用”,核心规则:</p>
<ul><li><strong>局部变量</strong>:函数内部定义的变量,仅在函数内部生效(出了函数就失效);</li><li><strong>全局变量</strong>:函数外部定义的变量,函数内部可访问,但 <strong>修改时需要用global</strong> 声明;</li><li><strong>同名变量</strong>:不同作用域可存在同名变量(本质是不同变量,互不影响)</li></ul>
<div class="jb51code"><pre class="brush:py;">x = 10
def test():
x = 20
print(f'函数内部:{x}')
test()
print(f'函数外部:{x}')
</pre></div>
<div class="jb51code"><pre class="brush:py;">x = 10
# 全局变量在函数里也可以使用
# def test():
# print(f'x = {x}')
#
# test()
# 使用这个函数,把全局变量 x 给改成 20!
def test():
global x
x = 20
test()
print(f'x = {x}')
</pre></div>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>1.3 函数的进阶用法(嵌套 + 递归)</h3>
<p><strong>(1)链式调用:把一个函数的返回值,作为另一个函数的参数</strong></p>
<div class="jb51code"><pre class="brush:py;">def isOdd(num):
if num % 2 == 0:
return False
return True
def add(x,y):
return x+y
# result = isOdd(10)
# print(result)
#
print(isOdd((add(5,5))))
</pre></div>
<p><strong>(2)嵌套调用:函数内部调用其他函数(包括自身)</strong></p>
<div class="jb51code"><pre class="brush:py;">def test():
print("hello")
test()
# 嵌套调用可以有很多层
def a():
num = 10
print("函数 a")
def b():
num = 20
a()
print("函数 b")
def c():
num = 30
b()
print("函数 c")
def d():
num = 40
c()
print("函数 d")
d()
</pre></div>
<p>函数之间的调用关系,在Python中会使用一个特定的数据结构来表示,称为 <strong>函数调用栈</strong>,每次函数调用,都会在调用栈里新增一个元素,称为 <strong>栈帧</strong>。</p>
<ul><li>可以通过 PyCharm 调试器看到函数调用栈和栈帧。</li><li>在调试状态下,PyCharm 左下角一般就会显示出函数调用栈。</li></ul>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011109331289.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011109331235.png" /></p>
<p>选择不同的栈帧,可以看到各自栈帧中的局部变量。</p>
<p><strong>思考</strong>:上述代码,a,b,c,d 函数中的局部变量名各不相同,如果变量名是相同的,比如都是 <code>num</code>,那么这四个函数中的 <code>num</code> 是属于同一个变量,还是不同变量呢? – <strong>不同变量</strong></p>
<p><strong>(3)递归调用:函数调用自身(慎用!)</strong></p>
<p>递归是嵌套调用的特使情况,核心是"有结束条件 + 每次逼近结束条件",否则会无限递归导致 <code>RecursionError</code></p>
<p><strong>案例</strong>:递归计算 5 的阶乘 (<code>5! = 5 * 4 * 3 * 2 * 1)</code></p>
<div class="jb51code"><pre class="brush:py;"># 写一个函数,来求 n 的阶乘(n是正整数)
# def factor(n):
# result = 1
# for i in range(1,n+1):
# result *= i
# return result
# 递归
# n! => n * (n-1)!
# 1! => 1
def factor(n):
if n == 1:
return 1
return n * factor(n - 1)
print(factor(5))
</pre></div>
<ul><li>务必存在递归结束条件,比如 <code>if n == 1</code> 就是结束条件。当 n 为 1 的时候,递归就结束了。</li><li>每次递归的时候,要保证函数的实参是逐渐逼近结束条件的。</li></ul>
<p><strong>⚠️ 注意</strong>:递归代码简洁但难理解,易栈溢出,实际开发中优先用循环替代。</p>
<p class="maodian"><a name="_lab2_1_3"></a></p><h3>1.4 函数核心小结</h3>
<p>掌握 3 点,搞定 Python 函数:</p>
<ul><li><strong>定义</strong>:<strong>def 函数名(形参):函数体 return 返回值</strong>;</li><li><strong>调用</strong>:函数名(实参),支持默认值,关键字参数;</li><li><strong>核心价值</strong>:复用代码,拆分逻辑,让程序更容易维护。</li></ul>
<p class="maodian"><a name="_label2"></a></p><h2>二. 列表和元组:批量存储数据的 “容器”</h2>
<p>当需要存储多个数据(比如10个学生的成绩,20个城市名)时,单独定义多个变量不现实,此时就需要列表(list)和元组(tuple)—— 它们是 Python 中最常用的 “序列类型”,专门用来批量存储数据。</p>
<p><strong>核心区别(一句话记牢):</strong></p>
<ul><li><strong>列表(list)</strong>:可变容器(像 “散装辣条”),元素可增删改;</li><li><strong>元组(tuple)</strong>:不可变容器(像 “包装辣条”),元素创建后无法修改。</li></ul>
<p class="maodian"><a name="_lab2_2_4"></a></p><h3>2.1 列表(list):最常用的可变容器</h3>
<p><strong>(1)创建列表</strong></p>
<p>两种核心方式,推荐用 <code>[ ]</code> (更简洁)</p>
<div class="jb51code"><pre class="brush:py;"># 创建列表
# 1. 直接使用字面值来创建
# [] 就表示一个 空的列表
a = []
print(type(a))
# 2. 使用 list() 来创建
b = list()
print(type(b))
# 3. 可以在创建列表的时候,在[]中指定列表的初始值
# 元素之间使用 , 来分割
a =
print(a)
# 4. 可以在同一个列表里放不同类型的变量
a = ]
print(a)
</pre></div>
<p>⚠️ 注意:不要用 <code>list</code> 作为变量名(会覆盖内置函数 <code>list()</code>),建议命名为 <code>list1,alist</code> 等。</p>
<p><strong>(2)列表的核心操作(必练)</strong></p>
<p>列表的操作都围绕 “下标” 展开,下标从 0 开始(负数表示倒数,<code>-1</code> 是最后一个元素),核心操作如下:</p>
<table><thead><tr><th>操作目的</th><th>代码示例</th><th>说明</th></tr></thead><tbody><tr><td>访问元素</td><td><code>list3</code></td><td>访问下标 2 的元素(list3 = 3),下标越界报 <code>IndexError</code></td></tr><tr><td>修改元素</td><td><code>list3 = 100</code></td><td>把下标 2 的元素改成 100,list3 变成 </td></tr><tr><td>切片(取子列表)</td><td><code>list3</code></td><td>取下标 1 到 3(左闭右开)的元素,输出 </td></tr><tr><td>新增元素</td><td><code>list3.append(5)</code></td><td>尾插(添加到末尾);<code>list3.insert(1, "a")</code>(插入到下标 1)</td></tr><tr><td>删除元素</td><td><code>list3.pop()</code></td><td>删除末尾元素;<code>list3.pop(2)</code>(删除下标 2 元素);<code>list3.remove(2)</code>(按值删除)</td></tr><tr><td>查找元素</td><td><code>2 in list3</code></td><td>判断元素是否存在(返回布尔值);<code>list3.index(2)</code>(找下标,不存在报异常)</td></tr><tr><td>连接列表</td><td><code>list3 + list4</code></td><td>拼接两个列表(生成新列表);<code>list3.extend(list4)</code>(拼接到 list3 末尾,修改原列表)</td></tr><tr><td>遍历元素</td><td><code>for elem in list3:</code></td><td>直接遍历元素(推荐);也可按下标遍历(<code>for i in range(len(list3))</code>)</td></tr></tbody></table>
<ul><li><strong>下标访问</strong>:</li></ul>
<div class="jb51code"><pre class="brush:py;"># 5. 使用下标来访问列表元素
a =
print(a) # 3
# 6. 使用下标来修改列表元素
a =
a = 100
print(a)
# 7. 超出下标有效范围,就会出现异常
# a =
# a = 0
# print(a)
# Traceback (most recent call last):
# File "D:\Gitee.code\python-fundamentals-\PythonProject\2025--11--24\code42.py", line 33, in <module>
# a = 0
# ~^^^^^
# IndexError: list assignment index out of range
# 8. 可以使用内建函数 len 来获取列表的长度(元素个数),和字符串类似
a =
print(len(a))
# 9. Python 中的下标,其实还可以写成负数!!!
# 例如写成 -1,其实等价于 len(a) - 1
a =
print(a)
# -1 就是倒数第一个元素
print(a[-1])
</pre></div>
<ul><li><strong>循环遍历</strong>:</li></ul>
<div class="jb51code"><pre class="brush:py;"># 1. 使用 for 循环来遍历列表
# 不会改变原来的数组
# a =
# for elem in a:
# elem = elem + 10
# print(elem)
# print(a)
# 2. 使用 for 循环遍历,通过下标的方式
# 会改变原来的数组
# a =
# for i in range(0,len(a)):
# a = a + 10
#
# print(a)
# 3. 使用 while 循环,通过下标遍历这个列表
a =
i = 0
while i < len(a):
print(a)
i += 1
</pre></div>
<ul><li><strong>增删查改 && 连接等</strong>:</li></ul>
<div class="jb51code"><pre class="brush:py;"># 1. 使用 append 往列表末尾新增一个元素
# a =
# a.append(5)
# a.append("hello")
# print(a)
# b =
# b.append("world")
# print(b)
# 2. 还可以使用 insert 方法,往列表的任意位置来新增元素
a =
a.insert(1,"hello")
a.insert(100,"hello") # 会在最后插入一个 hello
print(a)
</pre></div>
<div class="jb51code"><pre class="brush:py;"># 1. 使用 in 来判定某个元素是否在列表中存在
# a =
# print(1 in a)
# print(10 in a)
# print(1 not in a)
# print(10 not in a)
# 2. 使用 index 方法,来判定当前元素在列表中的位置,得到一个下标
a =
print(a.index(2))
print(a.index(3))
# print(a.index(10)) # 会报错
</pre></div>
<div class="jb51code"><pre class="brush:py;"># 1. 使用 pop 删除列表中的最末尾的元素
a =
a.pop()
print(a)
# 2. 使用 pop 还能删除任意位置的元素,pop的参数
a =
a.pop(1)
print(a)
# 3. 使用 remove 方法,可以按照值来进行删除
a = ["aa","bb","cc","dd"]
a.remove("cc")
print(a)
</pre></div>
<div class="jb51code"><pre class="brush:py;"># 1. 使用 + 针对两个列表进行拼接
# a =
# b =
# c = b + a
# print(c)
# c = a + b
# print(c)
# print(a)
# print(b)
# 2. 使用 extend 来进行拼接
# 这个拼接是把后一个列表的内容拼接到前一个列表里头
# a =
# b =
# c = a.extend(b) # extend 不返回任何内容
# a.extend(b)
# print(a) # a 这里改变了
# print(b)
# 3. 使用 += 来进行拼接
a =
b =
a += b# a = a + b
print(a)
print(b)
</pre></div>
<p><strong>(3)切片操作的灵活用法(重点)</strong></p>
<p>切片是列表的 “灵魂操作”,支持省略边界、指定步长(正数从左到右,负数从右到左):</p>
<div class="jb51code"><pre class="brush:py;"># 1. 切片操作的基本使用
a =
# 左闭右开区间
print(a)
# 2. 使用切片的时候,可以省略边界
a =
# 省略右边界,意思是从指定的开始位置,一直取到整个列表结束
print(a)
# 省略左边界,意思是从列表的 0 号元素开始取,一直取到指定的结束位置
print(a[:2])
# 此处切边中的下标也可以写成负数
print(a[:-1])
# 还可以把开始边界和结束边界都省掉,得到的就还是列表本身
print(a[:])
# 3. 带有步长的切片操作
a =
print(a[::1])
print(a[::2])
print(a[::3])
print(a)
# 4. 步长的数值还可以是负数,当步长为负数的时候,意思是从后往前来取元素
a =
print(a[::-1])
print(a[::-2])
# 5. 当切片中的范围超出有效下标之后,不会出现异常!,而是尽可能的把符合要求的元素给获取到
a =
print(a)
</pre></div>
<p class="maodian"><a name="_lab2_2_5"></a></p><h3>2.2 元组(tuple):不可变的序列容器</h3>
<p>元组的用法和列表几乎一致,但核心区别是"不可变"(元素无法增删改),适合存储不需要修改的数据(比如身份证号,坐标)。</p>
<p><strong>(1)创建元组</strong></p>
<p>用<code>()</code>表示,空元组用<code>()</code>或<code>tuple()</code>,注意单个元素的元组要加逗号(避免被当作普通括号):</p>
<div class="jb51code"><pre class="brush:py;"># 1. 创建元组
a = ()
print(type(a))
b = tuple()
print(type(b))
# 2. 创建元组的时候,指定初始值
a = (1,2,3,4)
print(a)
# 3. 元组中的元素也可以是任意类型的
a = (1,2,'hello',True,[])
print(a)
</pre></div>
<p><strong>(2)元组的核心操作</strong></p>
<ul><li><strong>支持的操作(和列表一致)</strong>:访问下标、切片、遍历、in判断、index查找、+拼接;</li><li><strong>不支持的操作(因为不可变)</strong>:修改元素、<code>append/insert/pop/remove/extend</code></li></ul>
<div class="jb51code"><pre class="brush:py;"># 4. 通过下标来访问元组中的元素,下标也是从 0 开始,到 len - 1 结束
a = (1,2,3,4)
print(a)
print(a[-1])
# print(a) # 错误
# 5. 通过切片来获取元组的一部分
a =
print(a)
# 6. 也同样可以使用 for 循环等方式来进行遍历元素
a = (1,2,3,4)
for elem in a:
print(elem)
# 7. 可以使用 in 来判断元素是否存在,使用 index 查找元素的下标
a = (1,2,3,4)
print(3 in a)
print(a.index(3))
# 8. 可以使用 + 来拼接两个元组
a = (1,2,3)
b = (4,5,6)
print(a + b)
# 9. 元组只支持 “读” 操作,不能支持 “修改” 操作
a = (1,2,3,4)
# 不支持以下修改的操作
# a = 100
# a.append(5)
# a.pop()
# a.extend()
# 10. 当进行多元赋值的时候,其实本质上是按照元组的方式来进行工作的,
def getPoint():
x = 10
y = 20
return x,y
x,y = getPoint()
print(type(getPoint()))
</pre></div>
<p><strong>(3)为什么有了列表,还需要元组?</strong></p>
<ul><li><strong>安全性:</strong> 传递数据时,用元组可避免数据被意外修改(比如传给一个未知函数,元组更安全);</li><li><strong>可作为字典的键:</strong> 后续要学的字典,键必须是 “可哈希对象”(不可变类型),元组可以,列表不行。</li></ul>
<p><strong>补充</strong>:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026011109331234.png" /></p>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>2.3 列表的元组小结</h3>
<table><thead><tr><th>特性</th><th>列表(list)</th><th>元组(tuple)</th></tr></thead><tbody><tr><td>定义方式</td><td><code>[]</code> 或 <code>list()</code></td><td><code>()</code> 或 <code>tuple()</code></td></tr><tr><td>是否可变</td><td>可变(增删改)</td><td>不可变(无增删改)</td></tr><tr><td>适用场景</td><td>需频繁修改数据(比如学生成绩)</td><td>数据无需修改(比如身份证号)</td></tr><tr><td>核心操作</td><td>支持所有序列操作 + 增删改</td><td>仅支持读操作,无写操作</td></tr></tbody></table>
<ul><li>列表和元组都是日常开发中最常用到的类型,最核心的操作就是根据 <code>[ ]</code> 来按下标操作。</li><li>在需要表示一个 “序列” 的场景下,就可以考虑使用列表和元组。</li><li>如果元素不需要改变,则优先考虑元组。</li><li>如果元素需要改变,则优先考虑列表。</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>结尾:</h2>
頁:
[1]