《流畅的Python》学习笔记-第一章python的数据类型(一)

写在前面

《流畅的Python》(Fluent Python)是一本由Luciano Ramalho编写的Python编程书籍。这本书的目标是帮助中级到高级Python程序员更深入地理解Python编程语言,以及如何以更加Pythonic(符合Python惯用法)的方式编写代码。这本书不仅介绍了Python的基本语法和特性,还探讨了Python中的高级概念、最佳实践和一些常用的设计模式。

这本书的主要内容包括:

1. Python数据模型:介绍了如何使用特殊方法来实现具有Pythonic行为的自定义对象。
2. 序列:深入讲解了列表、元组和字符串的内部实现和Pythonic用法。
3. 字典和集合:介绍了如何高效地使用这两种主要的Python数据结构。
4. 文本和字节:讲解了如何处理Unicode文本和二进制数据。
5. 第一类函数:深入讲解了如何处理函数作为对象,以及高阶函数的使用。
6. 设计模式:介绍了如何实现一些常用的设计模式,如装饰器、观察者和命令模式。
7. 并发编程:讲解了如何使用线程、进程和协程(coroutine)进行并发编程。
8. 元编程:深入学习如何使用元类、类装饰器和描述符进行元编程。

我将从2023年9月1日起更新学习这本书的一些笔记,本人基础较差所以学习起来会比较慢,内容也会比较详细~

python纸牌

实现原理

import collections # 导入collections模块

Card=collections.namedtuple('Card',['rank','suit']) # 定义一个namedtuple,用来表示一张牌
class FrenchDeck: # 定义一个类,用来表示一副扑克牌
    ranks=[str(n) for n in range(2,11)]+list('JQKA')# 定义牌的点数
    suits='spades diamonds clubs hearts'.split()# 定义牌的花色
    def __init__(self):# 初始化这副牌
        self._cards=[Card(rank,suit) for suit in self.suits
                                     for rank in self.ranks]
    def __len__(self):# 定义len函数
        return len(self._cards)
    def __getitem__(self,position):# 定义getitem函数
        return self._cards[position]
deck = FrenchDeck()# 创建一副扑克牌
print(len(deck))  # 输出:52,因为一副扑克牌有52张牌
print(deck[0])    # 输出:Card(rank='2', suit='spades'),即第一张牌:2 of spades
print(deck[-1])   # 输出:Card(rank='A', suit='hearts'),即最后一张牌:A of hearts
from random import choice
print(choice(deck))  # 输出:随机抽选一张牌
print(deck[:3])       # 输出:前三张牌
print(deck[12::13])   # 输出:A of spades, A of diamonds, A of clubs, A of hearts
for card in deck:     # 输出:一张张地打印出所有的牌
    print(card)
for card in reversed(deck):  # 输出:一张张地打印出所有的牌,但是顺序与上面相反
    print(card)
print(Card('Q','hearts') in deck)  # 输出:True,因为Q of hearts在这副牌中
print(Card('7','beasts') in deck)  # 输出:False,因为7 of beasts不在这副牌中
# 排序
suit_values=dict(spades=3,hearts=2,diamonds=1,clubs=0) # 为每个花色赋予一个权值
def spades_high(card): # 定义一个函数,用来对牌进行排序
    rank_value=FrenchDeck.ranks.index(card.rank)    # 获取牌的序号
    #在实例deck中,每一个元素都是一个tuple,我们获取这个tuple的属性rank,就等于得到了扑克牌的点数
    return rank_value*len(suit_values)+suit_values[card.suit]
    # 用点数乘以权值,再加上花色的权值,就得到了这张牌的权值
for card in sorted(deck,key=spades_high):
    print(card)
# 输出:
以上的python纸牌实现的完整代码,代码中出现了一些比较不熟悉的名词,比如namedtuple、init、getitem、sorted函数。下面我将详细解释,包含例子。
namedtuple对象

namedtuple是Python中collections模块提供的一个工具,它可以用来创建自定义的元组对象,并为元组中的每个位置分配一个名称。这使得代码可读性更高,同时保持了元组的不可变性。使用namedtuple创建的对象可以通过字段名称或索引访问元素,它还具有内置的__repr__方法,可以方便地显示对象的内容。

下面是一个如何使用namedtuple的例子:

from collections import namedtuple

# 创建一个名为Person的namedtuple,具有姓名、年龄和城市属性
Person = namedtuple('Person', ['name', 'age', 'city'])

# 使用 Person 创建一个新的对象
person1 = Person('Alice', 30, 'New York')

# 通过名称访问字段
print(person1.name) # 输出: Alice
print(person1.age) # 输出: 30
print(person1.city) # 输出: New York

# 通过索引访问字段
print(person1[0]) # 输出: Alice
print(person1[1]) # 输出: 30
print(person1[2]) # 输出: New York

# 使用内置的__repr__方法显示对象的内容
print(person1) # 输出: Person(name='Alice', age=30, city='New York')

namedtuple主要用于定义简单的类,当你需要一个具有特定属性的容器时,而不需要额外的方法、逻辑或其他功能时,它非常有用。这使得代码简洁,易于阅读和维护。

__init__方法

__init__方法是一个特殊的Python方法,称为类的构造函数或初始化方法。当您创建一个类的新实例时,__init__方法会自动调用。它的主要作用是为新创建的对象设置初始状态,这通常包括初始化属性和执行其他配置任务。

在Python中,特殊方法的名称以双下划线__开头和结尾,以区别于常规方法。__init__方法是一个非常常见的特殊方法,它在大多数类中都有定义。

以下是一个示例,展示了如何编写一个带有__init__方法的类:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hello(self):
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")

在这个例子中,我们定义了一个名为Person的类,它有一个__init__方法。__init__方法接收两个参数(除了self):nameage。当创建一个Person实例时,这些参数需要传递给构造函数:

person = Person("Alice", 30)

现在,Person实例已经创建并初始化了,我们可以调用say_hello方法:

person.say_hello() # 输出:Hello, my name is Alice and I am 30 years old.

在上述代码中,__init__方法负责将创建的对象的nameage属性初始化为传递给构造函数的值。

__getitem__方法

__getitem__方法是Python类的一个特殊方法,它使得类的实例可以使用方括号[]索引运算符访问其元素。当您尝试使用索引运算符访问类的实例时,Python会自动调用__getitem__方法。

在Python中,特殊方法的名称以双下划线__开头和结尾,以区别于常规方法。__getitem__方法通常在表示集合、序列或映射等具有元素的类中定义。

以下是一个示例,展示了如何编写包含__getitem__方法的类:

class MyList:
    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        return self.data[index]

在这个例子中,我们定义了一个名为MyList的类,它有一个__getitem__方法。这个方法接收一个参数(除了self):index,它指定了要访问的元素的索引。

现在,我们可以使用方括号[]索引运算符访问MyList实例的元素:

my_list = MyList([1, 2, 3, 4, 5])
print(my_list[1]) # 输出:2

在上述代码中,my_list[1]尝试访问MyList对象的第二个元素。Python将自动调用__getitem__方法并传递索引值1__getitem__方法将使用索引值从data属性中返回相应的元素。

sorted 函数

sorted函数是Python的内置函数,用于对列表、元组或其他可迭代对象中的元素进行排序。它会返回一个新的已排序列表,而不会修改原始的可迭代对象。

以下是sorted函数的一般用法:

sorted(iterable, *, key=None, reverse=False)

参数说明:

  1. iterable:一个可迭代对象(例如列表、元组、字典等),其中的元素将进行排序。
  2. key(可选):一个函数,用于确定排序中使用的值。这个函数应用于可迭代对象的每个元素,用于生成排序依据的键。默认值为None,表示直接使用元素本身的值进行排序。
  3. reverse(可选):一个布尔值,指定排序的顺序。True表示降序排序,False表示升序排序。默认值为False

以下是一些使用sorted函数的示例:

# 对数字列表升序排序
numbers = [4, 2, 9, 7, 5, 1, 8, 3, 6]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9]

# 对字符串列表按字母顺序排序
words = ["apple", "banana", "cherry", "orange", "grape"]
sorted_words = sorted(words)
print(sorted_words)  # 输出:['apple', 'banana', 'cherry', 'grape', 'orange']

# 使用 key 函数对字符串列表按字符串长度进行排序
sorted_words_by_length = sorted(words, key=len)
print(sorted_words_by_length)  # 输出:['apple', 'grape', 'banana', 'cherry', 'orange']

# 对数字列表降序排序
sorted_numbers_desc = sorted(numbers, reverse=True)
print(sorted_numbers_desc)  # 输出:[9, 8, 7, 6, 5, 4, 3, 2, 1]

需要注意的是,sorted函数返回一个新的已排序列表,而原始列表并未被修改。如果需要就地(in-place)排序列表,请使用列表对象的sort方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力毕业的每一天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值