前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >啃书---流畅的python : 第一章

啃书---流畅的python : 第一章

原创
作者头像
逸澄
发布2025-01-26 17:20:14
发布2025-01-26 17:20:14
6500
代码可运行
举报
运行总次数:0
代码可运行

数据类型

1 . 使用内置数据类型构造类

  1. 使用 collections.namedtuple, 创建可以用名字访问的tuple,可以通过名字来访问tuple 而不是使用索引。 如下所示
  2. 写在class 内的变量要通过self 来访问,否则会报找不到
  3. 两个魔术方法的使用: __len____getitem__; 使用__getitem__ 可以实现切片索引/random choice,迭代访问
  4. random 库中包含choice()可以随机从colletion 中选择一个输出
代码语言:python
代码运行次数:0
复制
import collections
point = collections.namedtuple("point",["x","y"])
#创建一个point 实例
a = point(5,4)
print(a)
#通过字段名访问:
print(a.x)
print(a.y)
代码语言:python
代码运行次数:0
复制
    point(x=5, y=4)
    5
    4

实现排序:

数学抽象: 本例子中包含两个维度的比较

  1. rank {2,3,4....K,A}
  2. 花色{"♣️",“♥️”,“♦️”,“♠️”} 可以将多个维度的值映射为唯一的数值。常见的方法是使用线形组合或笛卡尔积,结合每个维度可能值的数量来保证每个组合的唯一性。可以简化多维度排序和比较的问题,使得多个属性的组合能够在一个维度上得到有效表示。

线性组合方法

假设k个维度dim_1,dim_2,dim_3....dim_k ; 每个维度的可能取值集合分别是V_1,V_2,...V_k 假设维度$dim_i$的当前值为v_i \in V_i ,则将这k个维度的组合映射到一个唯一值的公式可以表示为:

\sum_{i=1}^{k}v_i \times \prod_{j=1}^{i=1}|V_j|

其中

  • v_i 是第i个维度
  • |V_j| 是第j个维度可能值的数量
  • \prod_{j=1}^{i-1}|V_j| 是所有在i之前的维度的可能值数的乘积,确保每个维度的值都在前面的维度数值范围内移动

例如:dim_1 =\{red,green,blue\}; dim_2=\{circle,square\},dim_3=\{small,medium,large\}

则计算公式为:

f(颜色,形状,大小) = (颜色编号)\times 形状总数\times 大小总数 + (形状编号)\times 大小总数+大小编号

代码语言:python
代码运行次数:0
复制
import collections
from random import choice
Card = collections.namedtuple('card',['rank','suit']) 
class FrenchDeck:
    ranks = [str(_) for _ in range(2,11)]+list("JQKA") #class 内的 注意通过self.ranks 来指向
    suits = 'spades diamonds clubs hearts'.split()
    def __init__(self):
        self._cards = [Card(rank,suit) for rank in self.ranks for suit in self.suits]
    def __len__(self):
        return len(self._cards)
    def __getitem__(self,position):
        return self._cards[position]
    
suits_val = dict(spades=3, hearts=2, diamonds=1, clubs=0) #给花色赋值
def spides_high(card):  #接受参数card,card 是一个Card 对象,包含rank 和suit
    ranks_val = FrenchDeck.ranks.index(card.rank) #FrenchDeck class 中的ranks ,card.rank 为当前card的排面值,
                                                  #index() 返回该card 在FrenchDeck.ranks 列表中的索引
    return ranks_val*len(suits_val)+suits_val[card.suit] # 用线性映射计算出来的唯一值

#------------------
cards = FrenchDeck()
print(len(cards))
print(choice(cards))
print("-----------------\n")
for card in sorted(cards,key=spides_high):
    print(card)
代码语言:python
代码运行次数:0
复制
    card(rank='5', suit='diamonds')
    -----------------
    
    card(rank='2', suit='clubs')
    card(rank='2', suit='diamonds')
    card(rank='2', suit='hearts')
    card(rank='2', suit='spades')
    card(rank='3', suit='clubs')
    card(rank='3', suit='diamonds')
    card(rank='3', suit='hearts')
    card(rank='3', suit='spades')
    card(rank='4', suit='clubs')
    card(rank='4', suit='diamonds')
    card(rank='4', suit='hearts')
    card(rank='4', suit='spades')
    card(rank='5', suit='clubs')
    card(rank='5', suit='diamonds')
    card(rank='5', suit='hearts')
    card(rank='5', suit='spades')
    card(rank='6', suit='clubs')
    card(rank='6', suit='diamonds')
    card(rank='6', suit='hearts')
    card(rank='6', suit='spades')
    card(rank='7', suit='clubs')
    card(rank='7', suit='diamonds')
    card(rank='7', suit='hearts')
    card(rank='7', suit='spades')
    card(rank='8', suit='clubs')
    card(rank='8', suit='diamonds')
    card(rank='8', suit='hearts')
    card(rank='8', suit='spades')
    card(rank='9', suit='clubs')
    card(rank='9', suit='diamonds')
    card(rank='9', suit='hearts')
    card(rank='9', suit='spades')
    card(rank='10', suit='clubs')
    card(rank='10', suit='diamonds')
    card(rank='10', suit='hearts')
    card(rank='10', suit='spades')
    card(rank='J', suit='clubs')
    card(rank='J', suit='diamonds')
    card(rank='J', suit='hearts')
    card(rank='J', suit='spades')
    card(rank='Q', suit='clubs')
    card(rank='Q', suit='diamonds')
    card(rank='Q', suit='hearts')
    card(rank='Q', suit='spades')
    card(rank='K', suit='clubs')
    card(rank='K', suit='diamonds')
    card(rank='K', suit='hearts')
    card(rank='K', suit='spades')
    card(rank='A', suit='clubs')
    card(rank='A', suit='diamonds')
    card(rank='A', suit='hearts')
    card(rank='A', suit='spades')

2. 特殊方法如何使用:

重载运算符

定义向量point 类,实现加法/乘法/取模操作

对象的字符串表示形式

__repr__

对象的布尔值

__bool__ : 若自定义class 中不显示的定义bool 函数, 则会自动调用类中的__len__ , 如果为0 则返回false ,否则返回true。 也可以自定一返回bool。注意__bool__方法必须返回一个bool值,因此显式的调用bool()函数

实现容器

代码语言:python
代码运行次数:0
复制
import math
class Point:
    def __init__(self,x=0,y=0):
        self.x =x
        self.y =y
    def __repr__(self):
        return f"Point({self.x },{self.y })" #
    def __add__(self,other):
        return Point(x=self.x+other.x,y=self.y+other.y)
    def __mul__(self,scale):
        return(Point(x=self.x*scale,y=self.y*scale))
    def __abs__(self):
        return math.hypot(self.x,self.y) #math 中用于计算欧几里得距离的函数,可以传入人任意个参数 ; = sqrt(x^2,y^2)
    def __bool__(self):
        return bool(self.x or self.y) #__bool__ 方法必须返回bool值,这里显式的调用了bool 函数
        
p1=Point(1,2)
p2 = Point(3,4)

print(f"p1+p2 = {p1+p2}")
print(f"p1*3={p1*3}")
print(f"abs(p1)={abs(p1)}")
代码语言:python
代码运行次数:0
复制
    p1+p2 = Point(4,6)
    p1*3=Point(3,6)
    abs(p1)=2.23606797749979

总结:

  1. 使用内置数据结构构件class 是第一次使用,排序方式是第一次使用。需要多加注意和练习
  2. 本章介绍的特殊方法使用频率较高,已经熟练
  3. 其他内容属于泛泛介绍,留待后序深入挖掘

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据类型
    • 1 . 使用内置数据类型构造类
    • 2. 特殊方法如何使用:
      • 重载运算符
      • 对象的字符串表示形式
      • 对象的布尔值
      • 实现容器
    • 总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档