7

几个易错的python小知识点 - 细水流深-LHF的博客

 11 months ago
source link: https://www.cnblogs.com/lianhaifeng/p/17751574.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

大家好,我是暴走の海鸽~

本期整理了几个基础python防坑小常识,希望对大家有所帮助。

1. type == object?

执行以下代码的结果是什么:

>>> isinstance(type, object)
True
>>> isinstance(object, type)
True
>>> isinstance(object, object)
True
>>> isinstance(type, type)
True
  • isinstance(type, object):这个表达式返回 True,因为在 Python 中,type 是一种类型,而 object 也是一种类型,它们都是对象的基类。

  • isinstance(object, type):同样返回 True,因为 object 是 Python 中所有对象的基类,因此它也可以被视为一种类型。

  • isinstance(object, object):这个表达式也返回 True,因为 object 是 object 类型的实例,它自己也是一种对象。

  • isinstance(type, type):同样返回 True,因为 type 本身也是一种类型,可以用来描述其他类型。

在 Python 中,所有东西都是对象,因此对于对象的任何实例检查都将返回True

  • isinstance(Anything, object) --> True

Python 的 type 表示构建所有 Python 类型的元类。因此,所有类型,如 int、str、object 都是 type 类的实例,而 type 类本身也是一个对象,与 Python 中的一切对象一样。

type 是 Python 中唯一一个自身是自己实例的对象。

2. all函数、any函数

执行以下代码的结果是什么:

>>> all([True, True, True])
True
>>> all([True, True, False])
False
>>>
>>>
>>> all([True, True, {}])
False
>>> any([True, True, {}])
True
>>>
>>> all([])
True
>>>
>>> any([])
False

根据内置函数any的定义,我们知道它将:

如果 iterable 中的任何元素为 true,则返回 true。

Python 中的逻辑运算符是惰性的,算法是查找第一个 true 元素的出现情况,如果没有找到,则返回 False。由于序列为空,因此没有元素可以是 true,因此 any([]) 返回 False。

all的例子稍微有些复杂,因为它表示真空的真实性。与链式惰性逻辑运算符类似,算法是查找第一个 false 元素,如果没有找到,则返回 True。由于在空序列中没有false 元素,因此 all([]) 返回 True。

>>> def my_all(iterable):
...     for element in iterable:
...         if not element:
...             return False
...     return True
...
>>> my_all([])
True
>>> my_all([True, True, {}])
False

3. 链式运算

执行以下代码的结果是什么:

>>> False == (False in [False])  # 这个好理解!
False
>>> (False == False) in [False]  # 这个也好理解!!
False
>>> True in [False]
False

>>> False == False in [False]  # 那这个是为什么呢?
True
1520561-20231009135737793-1893982871.png

在python中,==运算符和in运算符都具有相同的优先级,并且它们都是从左到右结合的。因此False == False in [False]实际上是(False == False) and (False in [False]的简写形式。

加个栗子理解下:

>>> '1' in '11' == True
False

>>> 4 > 3 == 3
True

'1' in '11' == True

python运算符优先级和结合性

4. sorted函数和reversed函数

执行以下代码的结果是什么:

>>> x = 1, 2, 3
>>>
>>> sorted(x) == x
False
>>>
>>> sorted(x)
[1, 2, 3]
>>> x
(1, 2, 3)
>>>
>>> y = reversed(x)
>>> sorted(y) == sorted(y)
False
>>>
>>>
>>> y
<reversed object at 0x7fb3aa5370>

注意:sorted 方法返回的是一个list,reversed 方法返回的是一个iterator。

5. 布尔值

执行以下代码的结果是什么:

>>> 1 == True
True
>>> False ** False == True
True
>>> 0 == False
True

Python 将 False 视为 0, True 视为 1

6. round函数

执行以下代码的结果是什么:

>>> round(1 / 2)
0
>>>
>>>
>>> round(3 / 2)
2
>>>
>>> round(5 / 2)
2

为什么 round(5 / 2) 返回 2 而不是 3?这里的问题在于 Python 的 round 方法实现了银行家舍入,其中所有半值都将四舍五入到最接近的偶数
即:

  • 如果小数部分小于 0.5,则舍弃小数部分,不进行舍入。

  • 如果小数部分大于 0.5,则向上舍入到最接近的整数。

  • 如果小数部分等于 0.5,且前一位的整数部分是奇数,则向上舍入到最接近的偶数。

  • 如果小数部分等于 0.5,且前一位的整数部分是偶数,则向下舍入到最接近的偶数。

7. python列表+和+=的区别

+

>>> a = [1, 2, 3]
>>> b = a
>>>
>>>
>>> a = a + [4]
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]

+=

>>> list1 = [1, 2, 3]
>>> list2 = list1
>>> list1 += list2
>>>
>>> list1
[1, 2, 3, 1, 2, 3]
>>> list2
[1, 2, 3, 1, 2, 3]
  • +用于连接两个列表,生成一个新的列表。
  • +=用于将一个列表与另一个列表相加,并将结果存储在原始列表中,修改原始列表。

8. 列表del元素

执行以下代码的结果是什么:

>>> my_list = [1, 2, 3, 4, 5]
>>> for i in range(len(my_list)):
...     if my_list[i] % 2 == 0:
...         del my_list[i]
...

执行结果:

>>> my_list = [1, 2, 3, 4, 5]
>>> for i in range(len(my_list)):
...     if my_list[i] % 2 == 0:
...         del my_list[i]
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range

在这个示例中,我们试图删除列表中的偶数元素。然而,这个代码会导致错误,因为在删除元素后,列表的长度发生变化,但循环中的索引 i 仍然会增加,这可能会导致索引超出列表边界的错误。

为了避免这种错误,可以使用以下方法之一来移除元素:

  1. 创建一个新列表,只包含要保留的元素,而不删除原始列表的元素。
my_list = [1, 2, 3, 4, 5]
new_list = [x for x in my_list if x % 2 != 0]
  1. 使用倒序循环,以避免索引问题。
my_list = [1, 2, 3, 4, 5]
for i in range(len(my_list) - 1, -1, -1):
    if my_list[i] % 2 == 0:
        del my_list[i]

这些方法可以避免在移除元素时引发错误,并确保代码正常运行。

9. 修改sum([])的默认返回值

我们知道sum([])的返回值为0,那有没有办法修改呢,比如返回0.0,答案是:有的。而且就在sum函数的签名里。

>>> sum("", [1])
[1]
>>> sum("", [1, 2])
[1, 2]
>>>
>>>
>>> sum([1, 2])
3
>>>
>>> sum([1, 2, 3], 1)
7
>>>
>>> sum([1, 2, 3], 9)
15

>>> sum([], {1, 2, 3})
{1, 2, 3}

>>> help(sum)
Help on built-in function sum in module builtins:

sum(iterable, /, start=0)
    Return the sum of a 'start' value (default: 0) plus an iterable of numbers

    When the iterable is empty, return the start value.
    This function is intended specifically for use with numeric values and may
    reject non-numeric types.

尽管如此,Python 仍然以其清晰透明的编程语言特性而闻名。在编写本文时,我遇到了许多这样的代码片段,它们可能在早期版本的 Python 中表现出反直觉的行为,但在新版本中得到了修复或社区的解释。上述示例代表了 Python 语法的某些边界情况,而在实际的商业项目中,遇到这些情况的机会相对较小。

然而,检查和理解这样的“陷阱”可以帮助您更深入地理解 Python 语言的内部结构,从而避免在编写代码时使用不常见的用例和可疑的编程做法,这可能会导致意外的错误和故障。因此,了解 Python 的行为和语法规则仍然是一个有价值的努力,尤其是对于那些希望编写高质量、可维护代码的开发人员来说。

❝ 喜欢这篇文章的话,就点个关注吧,或者关注一下我的公众号『海哥python』也可以,会持续分享高质量Python文章,以及其它内容。❞


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK