首页 > 编程语言 > 详细

流畅的python笔记

时间:2019-05-15 19:37:02      阅读:83      评论:0      收藏:0      [点我收藏+]

1、collection.nametuple是一个工厂函数,可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便,而不需要重新定义一个类那么麻烦。

#nametuple的属性和方法
City._fields #(‘name‘, ‘country‘, ‘population‘, ‘coordinates‘)

_make(iterable)  #类方法, 对可迭代对象进行实例化
_asdict()  #实例方法,把nametuple以collections.OrderedDict的形式返回,使其友好呈现

 

2、定义类的一些技巧

import collections
Card = collections.namedtuple(Card, [rank, suit]) #避免自定义class的麻烦

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()__:
    return len(self._cards)
  
  def __getitem__(self, position): #实现该方法即实现可迭代,因此in运算符可以使用
    return self._cards[position] #支持切片

 

3、

from math import hypot

class Vector:
  def __init__(self, x=0, y=0):
    self.x = x
    self.y = y
  
  def __repr__(self): #把一个对象用字符串的形式表达出来,__repr__比__str__是更好的选择,__str__是给终端看的,__repr__调试用
    return Vector(%r, %r) % (self.x, self.y)
  
  def __abs__(self):
    return hypot(self.x, self.y)
  
  def __bool__(self):
    return bool(abs(self)) # return bool(self.x, self.y)更高效,省掉abs到__abs__的转化
  
  def __add__(self, other):
    x = self.x + other.x
    y = self.y + other.y
    return Vector(x, y)
  
  def __mul__(self, scalar):
    return Vector(self.x * scalar, self.y * scalar)

还有一系列的特殊方法。

 

4、为什么len不是普通的方法?运行更快。

5、

容器序列(存放不同类型):list, tuple, collections.deque

扁平序列(存放单类型):  str, bytes, bytearray, memoryview, array.array

 

6、列表推导

codes = [ord(symbol) for symbol in symbols]

同filter和map的比较,列表推导都能做,而且不用lambda

beyond_ascii = [ord(s) for s in symbols if ord(s)>127]
beyond_ascii = list(filter(lambda c:c>127, map(ord, symbols)))

 

7、生成器表达式:逐个生成,节省内存,注意是()

tuple(ord(symbol) for symbol in symbols)

 

8、可以使用*运算符把一个可迭代对象拆开作为函数的参数。

t = (20, 8) #可迭代对象
divmod(*t) 

还可以使用*来获取不确定的参数

a, b, *rest = range(5) #(0,1,[2,3,4])

 

9、二维的numpy可以使用二维切片 [ m:n, k:l ],如果x是四维数组,x[ i, ...] 就是 x[i, :, :, : ]。

如果赋值的对象是一个切片,那么赋值右边必须是个可迭代的对象。

l[ 2:5 ] = [100] #
l[ 2:5 ] = 100   #

 

10、

board = [ [_] * 3 for i in range[3]]
weird_board = [ [_] * 3] *3 #单点赋值会修改多个点,原因是列表内的3个引用指向同一个对象

 

11、

*= 在可变序列上不会改变序列ID,但在不可变的序列(如tuple)会改变ID,原因是对不可变序列进行重复拼接效率很低,因为每次都要把旧对象的元素赋值到新对象里,再追加元素。

 

12、一个谜题

t = (1, 2, [30, 40])
t[2] += [50, 60]

#结果有两个:
#元组不可赋值,会抛出异常,还会把t改变了:
#t变成 ( 1, 2, [30, 40, 50, 60] )

鉴于上面的情况,建议:不要把可变对象放在元组里面,增量赋值不是一个原子操作(像上面的例子)

 

13、list.sort 返回None,sorted返回新建的排序列表

 

14、使用bisect来管理已排序的序列。

#该模块不会影响原排序
bisect.insort() #插入并改变原序列
bisect.bisect() #插入但不改变原序列
bisect.bisect_left() #插在重复数字的左边,返回插入位置,不改变原序列

15、

存放大量浮点数是,数组(array)的效率更高。

检查一个元素是否出现在一个集合中,set更合适。

如果只包含数字的列表,那么array.array比list更高效。数组还提供从文件读取和存入文件的更快的方法,如.frombytes和.tofile。

pickle.dump的处理速度和array.tofile一样快。

 

16、内存视图memoryview

让用户在不复制内容的情况下操作同一个数组的不同切片。

 

17、dict,defaultdict,OrderedDict

defaultdict在未找到的元素时,补上默认构造。(注意被__getitem__调用的__missing__方法)

dict.setdefault的妙用(一句顶三句):

index.setdefault(word, []).append(location) #检索word,不存在则返回[ ],然后在该[ ]后添加位置。 

if key not in my_dict:
  my_dict[key] = []
my_dict[key].append(new_value)

 

流畅的python笔记

原文:https://www.cnblogs.com/hotsnow/p/10871460.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!