首页 > Python资料 博客日记
Python 初学者容易踩的坑
2024-03-11 19:00:03Python资料围观132次
哈喽大家好,我是咸鱼。
今天咸鱼列出了一些大家在初学 Python 的时候容易踩的一些坑,看看你有没有中招过。
原文:https://www.bitecode.dev/p/unexpected-python-traps-for-beginners
不明显的字符串拼接
Python 在词法分析的时候会把多个字符串自动拼接起来。
data = "very""lazy"
print(data) # verylazy
这个特性可以让我们在声明一个长字符串的时候可以分成多行来写,这样看起来比较优雅。
msg = (
"I want this to be on a single line when it prints "
"but I want it to be broken into several lines in "
"the code"
)
print(msg)
# I want this to be on a single line when it prints but I want it to be broken into several lines in the code
msg ="I want this to be on a single line when it prints " \
"but I want it to be broken into several lines in " \
"the code"
print(msg)
# I want this to be on a single line when it prints but I want it to be broken into several lines in the code
但初学者往往会忽略这一点,他们在使用包含字符串的列表时把分隔符漏掉,造成了意想不到的字符串拼接。
比如说他们想要声明一个包含域名的列表host。
host = [
"localhost",
"bitecode.dev",
"www.bitecode.dev"
]
print(host) # ['localhost', 'bitecode.dev', 'www.bitecode.dev']
但是写成了下面这样。
host = [
"localhost",
"127.0.0.1",
"bitecode.dev" # 这里把逗号忘掉了
"www.bitecode.dev"
]
print(host) # ['localhost', 'bitecode.devwww.bitecode.dev']
这是有效的代码,不会触发语法错误,但是解析的时候会把 "bitecode.dev"
和 "www.bitecode.dev"
拼接在一起,变成 'bitecode.devwww.bitecode.dev'
。
sorted() 和 .sort() 傻傻分不清
在 Python 中,大多数函数或方法都会返回一个值。比如说我们要对一个列表里面的内容进行排序,可以使用 sorted()
方法。
# sorted() 方法会返回一个排序后的新列表
numbers = [4, 2, 3]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # [2, 3, 4]
我们也可以用列表自带的 .sort()
方法来排序,需要注意的是: .sort()
直接对原有列表进行排序,不会返回任何值。
# .sort() 方法直接对原列表进行排序
numbers = [4, 2, 3]
numbers.sort()
print(numbers) # [2, 3, 4]
但是初学者很容易把 sorted()
的用法用在 .sort()
上,结果发现怎么返回了一个 None。
numbers = [4, 2, 3]
sorted_numbers = numbers.sort()
print(sorted_numbers) # None
list.sort()
修改原列表,它不会返回任何内容。当 Python 可调用对象不返回任何内容时,会得到 None
。
或者把 .sort()
的用法用在了 sorted()
上。
numbers = [4, 2, 3]
sorted(numbers)
print(numbers) # [4, 2, 3]
不要乱加尾随逗号
我们在创建一个空元组的时候可以用下面的两种方法:
t1 = ()
t2 = tuple()
print(type(t1))
print(type(t2))
在 Python 中,虽然元组通常都是使用一对小括号将元素包围起来的,但是小括号不是必须的,只要将各元素用逗号隔开,Python 就会将其视为元组。
t1 = 1,
print(t1) # (1,)
print(type(t1)) # <class 'tuple'>
所以如果在数据后面多加了一个逗号,就会产生一些问题。
比如说下面是一个列表:
colors = [
'red',
'blue',
'green',
]
print(colors) # ['red', 'blue', 'green']
如果不小心加了一个尾随逗号,列表就变成了元组。
colors = [
'red',
'blue',
'green',
],
print(colors) # (['red', 'blue', 'green'],)
在 python 中,包含一个元素的元组必须有逗号,比如下面是包含一个列表的元组:
colors = [
'red',
'blue',
'green',
],
这是列表:
colors = ([
'red',
'blue',
'green',
])
可怕的 is
在 python 中, is 和 == 都是用来比较 python 对象的,区别是:
- is 比较需要对象的值和内存地址都相等
- == 比较只需要对象的值相等就行了
事实上,这两者的实际使用要远远复杂的多。
比如说下面的 a 和 b 是两个不同的对象,a is b
应该返回 False,但是却返回了 True。
a = 4
b = 4
print(a == b) # True
print(a is b) # True
在 python 中,由于小整数池和缓存机制,使用 is 来比较对象往往会出现意想不到的结果。
关于小整数池和缓存机制可以看我这篇文章:
奇怪的引用
在Python中,如果 *
运算符用于数字与非数字型数据(列表、字符串、元组等)的结合,它将重复非数字型数据。
print("0" * 3) # '000'
print((0,) * 3) # (0, 0, 0)
在创建一个多个列表元素的元组时候,如果使用下面的代码:
t1 = ([0],) * 3
print(t1) # ([0], [0], [0])
会带来意想不到的问题:我们对元组中的第一个列表元素中的数据进行算数运算(自增 1)
t1[0][0] += 1
print(t1) # ([1], [1], [1])
我们发现元组中的所有列表元素内的数据都自增 1 了,我们不是只对第一个列表元素进行自增的吗?
实际上,当我们执行 t1 = ([0],) * 3
的时候,不会创建一个包含三个列表组成的元组,而是创建一个包含 3 个 引用的元组,每个引用都指向同一个列表。
元组中的每个元素都是对同一个可变对象(列表)的引用,所以当我们修改其中的元素时,另外的对象也会跟着发生变化。
正确的方法应该是:
t2 = ([0], [0], [0])
# 或者 t2 = tuple([0] for _ in range(3))
t2[0][0] += 1
print(t2) # ([1], [0], [0])
在 python 的其他地方中也有这种类似的坑:
def a_bugged_function(reused_list=[]):
reused_list.append("woops")
return reused_list
print(a_bugged_function()) # ['woops']
print(a_bugged_function()) # ['woops', 'woops']
print(a_bugged_function()) # ['woops', 'woops', 'woops']
可以看到,reused_list
在函数定义中被初始化为一个空列表 []
,然后每次函数调用时都使用这个默认的空列表。
在第一次调用 a_bugged_function()
后,列表变成了 ['woops']
。然后,在第二次和第三次调用中,它分别继续被修改,导致输出的结果为:
['woops']
['woops', 'woops']
['woops', 'woops', 'woops']
这是因为在函数定义中,如果将可变对象(例如列表)作为默认参数,会导致该对象在函数调用时被共享和修改:每次调用函数时,使用的都是同一个列表对象的引用。
为了避免这种情况,常见的做法是使用不可变对象(如 None
)作为默认值,并在函数内部根据需要创建新的可变对象。
def a_fixed_function(reused_list=None):
if reused_list is None:
reused_list = []
reused_list.append("woops")
return reused_list
print(a_fixed_function())
print(a_fixed_function())
print(a_fixed_function())
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj