分类: Python

Python 变量的赋值与对象引用

诸如list的可变类型,变量赋值时原变量与新变量指向同一对象

1. 对象引用

在 Python 中,变量保存的不是对象本身,而是对对象的引用。赋值操作(例如 a = b)会复制引用,而不是创建新的对象。这意味着 ab 指向同一块内存中的对象,因此对可变对象的修改会在所有指向该对象的变量中生效。

   a = [1, 2, 3]
   b = a  # b 和 a 指向同一个对象
   b[0] = 99
   print(a)  # 输出: [99, 2, 3]

2. 可变和不可变类型

  • 不可变类型:包括 int(整数)、float(浮点数)、str(字符串)、tuple(元组)等。这些对象一旦创建,其内容就无法改变。每次尝试修改会创建一个新对象,而不会改变原有对象。
    python x = 10 y = x y = 20 print(x) # 输出: 10,不受 y 修改的影响
  • 可变类型:包括 list(列表)、dict(字典)、set(集合)等。这些对象可以直接修改其内容,不需要创建新对象,因此所有指向该对象的引用都会受到影响。

3. 浅拷贝与深拷贝

  • 浅拷贝:只复制对象的本身,但对于对象中的嵌套可变对象,仅复制其引用。也就是说,浅拷贝后的对象与原始对象共享内部嵌套对象。 import copy original = [[1, 2], [3, 4]] shallow_copy = copy.copy(original) shallow_copy[0][0] = 99 print(original) # 输出: [[99, 2], [3, 4]]
  • 深拷贝:复制对象及其所有嵌套对象,确保新对象完全独立于原始对象。深拷贝不会共享任何嵌套对象的引用。
    python deep_copy = copy.deepcopy(original) deep_copy[0][0] = 42 print(original) # 输出: [[99, 2], [3, 4]]

总结

  • 引用:Python 中变量是对象的引用,赋值是引用的复制。
  • 可变与不可变类型:不可变类型一旦创建无法更改;可变类型可以更改且会影响所有引用。
  • 浅拷贝与深拷贝:浅拷贝共享嵌套对象引用,深拷贝完全独立,适用于复杂嵌套结构的复制。

Python float类型的比较

在 Python 中比较浮点数时,由于浮点数的精度限制,直接使用 == 来判断两个浮点数是否相等通常是不可靠的。可以通过设置比较精度(容许误差)来判断两个浮点数是否在特定范围内相等。常用的方法如下:

1. 使用内置的 math.isclose() 函数

Python 3.5 引入了 math.isclose() 函数,用于比较两个浮点数是否接近相等。此函数允许设置相对误差和绝对误差,以控制比较精度。

import math

a = 0.1 + 0.2
b = 0.3

# 使用默认精度(相对误差 1e-09)
print(math.isclose(a, b))  # 输出: True

# 设置更高的精度
print(math.isclose(a, b, rel_tol=1e-10, abs_tol=1e-10))
  • rel_tol:相对误差容忍度,默认为 1e-09
  • abs_tol:绝对误差容忍度,默认值为 0.0。适合比较非常小的数时使用。

2. 使用自定义误差范围

如果需要手动设置精度,也可以通过自定义误差范围进行比较。

def is_close(a, b, tol=1e-9):
return abs(a - b) < tol

a = 0.1 + 0.2
b = 0.3
print(is_close(a, b)) # 输出: True

3. 使用 decimal 模块

对于高精度计算,decimal 模块可以更精确地控制小数位数。将浮点数转换为 Decimal 对象后,可以设定精度进行比较。

from decimal import Decimal, getcontext

# 设置精度
getcontext().prec = 10

a = Decimal('0.1') + Decimal('0.2')
b = Decimal('0.3')
print(a == b) # 输出: True

4. 使用 numpy.isclose()(适合科学计算)

numpy.isclose() 是 NumPy 提供的类似 math.isclose() 的函数,适用于比较数组中的浮点数。

import numpy as np

a = 0.1 + 0.2
b = 0.3
print(np.isclose(a, b)) # 输出: True

Powered by WordPress & Theme by Anders Norén