1.现在在看《流畅的Python》这本书,看了三页就发现,这本书果然不是让新手来入门的,一些很常见的知识点能被这个作者玩出花来,

唉,我就在想,下面要分析的这些的代码,就算我费劲巴拉的看懂了,又有什么用呢,我其实不想靠着技术吃饭,但是现在在这个岗位上,

就得在其位谋其职,悲哀。我在敲代码方面也没什么天赋,也没什么热情,老话说得好,‘女怕嫁错郎,男怕入错行’,

所以我得从IT行业抽出身来。anyway,进入正题。

2.python解释器碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开头,

以两个下划线结尾(例如__getitem__)。比如obj[key]的背后就是__getitem__方法,为了求得my_collection[key]的值,解释器实际上会调用my_collection.__getitem__(key),双下划线这种特殊方法也叫双下方法(dunder method).

import collections

Card = collections.namedtuple('Card',['rank','suit'])

class FrenchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
# ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
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):
# print("用的是我写的lenth")
# 如果不写这个方法,用len(deck)时会报错:TypeError: object of type 'FrenchDeck' has no len()
return len(self._cards) def __getitem__(self, position):
return self._cards[position]
>>> beer_card = Card('7','hearts')
>>> beer_card
Card(rank='7', suit='hearts')
这张牌就是红心7
FrenchDeck类中的self._cards生成了一个有52张'牌'的列表
[Card(rank='2', suit='spades'), Card(rank='3', suit='spades'), ...共52个]
suits = ['spades', 'diamonds', 'clubs', 'hearts']
namedtuple的作用:
>>> beer_card = Card('7','hearts')
>>> beer_card
Card(rank='7', suit='hearts')
FrenchDeck类支持的方法:
>>> deck = FrenchDeck()
>>> len(deck)
52
>>> from random import choice
>>> choice(deck)
支持分片:只看牌面是A的牌--先抽出索引是12的那张牌,然后每隔13张拿一张
>>> deck[12::13]
[Card(rank='A', suit='spades'), Card(rank='A', suit='diamonds'),
Card(rank='A', suit='clubs'), Card(rank='A', suit='hearts')]
这个我觉得作者的用法很好
仅仅用__getitem__方法,使这一摞牌变成可迭代
>>> for card in deck:
... print(card)
反向迭代
>>> for card in reversed(deck):
... print(card)
一个集合类型如果没有实现__contains__方法,in运算符就会按顺序做一次迭代搜索
>>> Card(rank='A', suit='spades') in deck
True

下面这段就厉害了,弄得我眼黑头晕的,弄了一早上才搞明白,怎么对这些扑克牌进行排序?

首先你会想到sorted,但我连它的key参数都不会用,何谈去排序这些扑克。sorted用法:

sorted最简单用法是对元素全部是数字的列表排序,另一种用法是对元素是元组或字典的列表排序

用到的参数是key,比如:对学生的分数进行排序:

list1 = [('david', 90), ('mary',90), ('sara',80),('lily',95)]
sorted(list1, key=lambda x: x[0]) # 按照元组中第一个元素排序
sorted(list1, key=lambda x: x[1]) # 按照元组中第二个元素排序
array = [{"age":20,"name":"a"},{"age":25,"name":"b"},{"age":10,"name":"c"}]
array1 = sorted(array,key=lambda x:x["age"]) # 按照年龄排序

下面要讲的例子,先抛个砖:

1.需求:将列表中的元素按照绝对值大小进行升序排列
list1 = [3,5,-4,-1,0,-2,-6]
sorted(list1, key=lambda x: abs(x)) 当然,也可以如下: list1 = [3,5,-4,-1,0,-2,-6]
def get_abs(x):
return abs(x)
sorted(list1,key=get_abs)
只不过这种方式的代码看起来不够Pythonic
2、应用在闭包中
def get_y(a,b):
return lambda x:ax+b
y1 = get_y(1,1)
y1(1) # 结果为2 当然,也可以用常规函数实现闭包,如下: def get_y(a,b):
def func(x):
return ax+b
return func
y1 = get_y(1,1)
y1(1) # 结果为2
只不过这种方式显得有点啰嗦。
那么是不是任何情况下lambda函数都要比常规函数更清晰明了呢?
Python之禅中有这么一句话:Explicit is better than implicit(明了胜于晦涩),就是说那种方式更清晰就用哪一种方式,不要盲目的都使用lambda表达式。

扑克牌排序代码:

suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
# {'clubs': 0, 'diamonds': 1, 'spades': 3, 'hearts': 2} def spades_high(card):
rank_values = FrenchDeck.ranks.index(card.rank)
return rank_values * len(suit_values) + suit_values[card.suit] for card in sorted(deck,key=spades_high):
print(card)

一、这段代码我看了很长时间,这本书的作者竟然将这段代码放在书的第二页,我也是醉了,我觉得是挺难的,但不管怎样,硬着头皮上吧!

扑克牌排序规则:

用点数来判断扑克牌的大小,2最小,A最大;同时还要加上对花色的判断:

黑桃最大,红桃次之,方块再次,梅花最小。那么梅花2的大小是0,黑桃A是51.

分析一下这个函数:sorted(deck,key=spades_high),我在这里卡了很长时间,所以就有了上面的那块砖,先说一下这个函数是怎么运行的吧:

通过sorted将deck这一摞牌和排序函数spades_high()联系起来,每张牌都有数字,先获取牌面的数字在FrenchDeck.ranks中的索引,即:2的索引0,

3的索引1,4的索引2,类推3,4,5,6,7,8,9,10,11,A的索引12,这张牌多大取决于它的花色,即索引 乘 4 加 花色值,

二、spades_high(card),这里的card就是传进来的每一张牌,rank_values = FrenchDeck.ranks.index(card.rank),

获取这张纸牌(即纸牌的数字)在FrenchDeck.ranks中的索引,['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']

"最后返回这个牌的得分",rank_values * len(suit_values) + suit_values[card.suit],此时就讲完了么?

灵光一闪,这个函数返回了所有得分有什么用?sorted()拿到这些得分,怎么把牌排好序?我觉得是这样:

在得到了[所有得分]这个列表之后,进行排序,得到:[0,1,2,3,4,...51],

然后将原扑克列表中的元素,一一对应,是怎么对应的?函数在处理的时候应该记录了每张卡的得分,所以能对应上。

如下(原来的扑克列表可不是这样的,排好序的应该是重新开辟了一个内存空间):

[Card(rank='2', suit='clubs'),Card(rank='2', suit='diamonds'),Card(rank='2', suit='hearts'),...Card(rank='A', suit='spades')]

三、比如上面第一块砖:

list1 = [3,5,-4,-1,0,-2,-6]

def get_abs(x):
    return abs(x)
sorted(list1,key=get_abs)

函数先返回[3,5,4,1,0,2,6],然后排序[0,1,2,3,4,5,6],接着将list1中的每个元素,与排序后的列表对应,

0不变,1、2变成-1、-2,3不变,4变成-4,5不变,6变成-6,输出[0,-1,-2,3,-4,5,-6]

四、看不懂的lambda,只是把这两道题放在在这里提醒我,不要迷进去:

一道面试题:
list1=[7, -8, 5, 4, 0, -2, -5]
要求1.正数在前负数在后 2.整数从小到大 3.负数从大到小
解题思路:先按照正负排先后,再按照大小排先后
list1=[7, -8, 5, 4, 0, -2, -5]
print(sorted(list1,key=lambda x:(x<0,abs(x))))
[7, 5, 4, 0, -8, -2, -5]
[0, 4, 5, 7, -2, -5, -8] 一个经典的复杂例子
这是一个字符串排序,排序规则:小写<大写<奇数<偶数
s = ‘asdf234GDSdsf23’ #排序:小写-大写-奇数-偶数
print(“”.join(sorted(s, key=lambda x: (x.isdigit(),x.isdigit() and int(x) % 2 == 0,x.isupper(),x))))
原理:先比较元组的第一个值,FALSE

也不说什么脏话了,反正没什么成就感,这些东西耗费我整整一天时间啊,就这本书作者随手扔出来的一些小玩意,搞得我很不堪,

这就是传说当中的以我之短击他之长吧,法克!但还是会有不服,别人能会,我为什么嫌难,人总是活在矛盾中。总之,以后尽量不搞这些东西了。

《流畅的Python》一副扑克牌中的难点的更多相关文章

  1. 【转】从一副扑克牌中随机抽取N张

    该问题为产生不重复的随机数序列,形象点就是一副扑克牌中随机抽取N张. 摘自:不重复随机数列生成算法 改了一部分 /** * 从0-max随机选N个数出来 * **/ public static int ...

  2. C语言:判断t所指字符串中的字母是否由连续递增字母组成。-判断一个输入的任何整数n,是否等于某个连续正整数序列之和。-将一副扑克牌编号为1到54,以某种方式洗牌,这种方式是将这副牌分成两半,然后将他们交叉,并始终保持编号1的牌在最上方。

    //判断t所指字符串中的字母是否由连续递增字母组成. #include <stdio.h> #include <string.h> void NONO(); int fun( ...

  3. 《流畅的python》读书笔记

    流畅的python 第1章 python数据模型 ---1.1 一摞Python风格的纸牌 特殊方法,即__method__,又被称为魔术方法(magic method)或者双下方法(dunder-m ...

  4. 流畅的python(笔记)

    流畅的python中有很多奇技淫巧,整本书都在强调如何最大限度地利用Python 标准库.介绍了很多python的不常用的数据类型.操作.库等,对于入门python后想要提升对python的认识应该有 ...

  5. 流畅的python 对象引用 可变性和垃圾回收

    对象引用.可变性和垃圾回收 变量不是盒子 人们经常使用“变量是盒子”这样的比喻,但是这有碍于理解面向对象语言中的引用式变量.Python 变量类似于 Java 中的引用式变量,因此最好把它们理解为附加 ...

  6. [读书笔记]流畅的Python(Fluent Python)

    <流畅的Python>这本书是图灵科技翻译出版的一本书,作者Luciano Ramalho. 作者从Python的特性角度出发,以Python的数据模型和特殊方法为主线,主要介绍了pyth ...

  7. 《流畅的Python》Object References, Mutability, and Recycling--第8章

    Object References, Mutability, and Recycling 本章章节: Variables Are Not Boxes identity , Equality ,  Al ...

  8. SyntaxError: Non-UTF-8 code starting with '\xbb' in file D:\流畅学python\ex32.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

    1. 报错如下: SyntaxError: Non-UTF-8 code starting with '\xd3' in file D:\流畅学python\ex34.py on line 4, bu ...

  9. 如何使用Python在Kaggle竞赛中成为Top15

    如何使用Python在Kaggle竞赛中成为Top15 Kaggle比赛是一个学习数据科学和投资时间的非常的方式,我自己通过Kaggle学习到了很多数据科学的概念和思想,在我学习编程之后的几个月就开始 ...

随机推荐

  1. POI创建生成excel及设置相关属性

    简单的读写到excel中: import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io. ...

  2. SpringBoot整合升级Spring Security 报错 【The request was rejected because the URL was not normalized】

    前言 最近LZ给项目框架升级, 从Spring1.x升级到Spring2.x, 在这里就不多赘述两个版本之间的区别以及升级的原因. 关于升级过程中踩的坑,在其他博文中会做比较详细的记录,以便给读者参考 ...

  3. 121. Best Time to Buy and Sell Stock@python

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  4. c++ 递归求一个数的阶乘

    #include <iostream> using namespace std; long factorial(int value); int main() { int value; co ...

  5. (55)zabbix模板嵌套

    在zabbix使用过程中,在某些情况下,一个host需要link多个模板.这么做显得比较麻烦,很容易忘记到底要link哪些模板,我想link一个模板就达成这个目标,行不行?然没问题,zabbix模板内 ...

  6. nginx + 一个端口 部署多个单页应用(history模式)

    目前web开发 使用一般前后端分离技术,并且前端负责路由.为了美观,会采用前端会采用h5 history 模式的路由.但刷新页面时,前端真的会按照假路由去后端寻找文件.此时,后端必须返回index(i ...

  7. 基于IAR移植sdk12.2.0建立nrf52832的工程———GPIO

    工程伊始,需要在sdk包中拷贝三个重要的文件,blinky_iar_nRF5x.icf,iar_startup_nrf52.s,system_nrf52.c. 工程目录建立: 1.建立bsp文件,包括 ...

  8. Jmeter接口测试-简单分析结果数、聚合报告以及图形结果(二)

    简单分析结果数.聚合报告以及图形结果 结果树 取样器结果:返回值报200,表示执行接口调试成功 请求:发送的数据 响应数据:返回的数据 Thread Name:线程组名称 Sample Start: ...

  9. [BZOJ1582] [Usaco2009 Hol]Holiday Painting 节日画画(线段树)

    传送门 线段树区间修改傻题 #include <cstdio> #include <cstring> #include <iostream> #define N 5 ...

  10. USACO 2.1 The Castle

    题目大意:给你一个城堡让你求有多少房间,最大房间有多大,敲掉一堵墙后最大的房间有多大,敲掉那座墙 思路:比较恶心的bfs题,反正就是bfs使劲敲 /*{ ID:a4298442 PROB:castle ...