python cookbook

1.星号表达式

星号解压 : 实际上 *args 可以表示很多值.

In [1]: for tag, *args in [('foo',1,2),('bar','hello')]:
   ...:     print(tag)
   ...:     print(*args)
   ...:     print('\n')
   ...:     
foo
1 2


bar
hello

接下来,请注意与以上的区别

In [2]: for tag, *args in [('foo',1,2),('bar','hello')]:
   ...:     print(tag)
   ...:     print(args)
   ...:     print('\n')
   ...:     
foo
[1, 2]


bar
['hello']

当你给值赋予变量,且值的个数不确定的时候.可以使用星号表达式 , *args 可以生成任意个变量 . 但是此时args是一个列表.如果想要将列表中的元素分别传递,那么你需要 *args 进行 ' 解压 '.对,没错,就是解压.

请看下面的练习

>>> items = [1, 10, 7, 4, 5, 9]
>>> head, *tail = items
>>> head
1
>>> tail
[10, 7, 4, 5, 9]
>>>

2.deque(maxlen=N)构造函数

这个函数会新建一个固定大小的队列.当新的元素加入并且这个队列已经满的时候,最老的元素会自动被移除掉.

In [3]: from collections import deque

In [4]: q = deque()

In [5]: q.append(2)

In [6]: q.append(3444)

In [7]: q.append(99)

In [8]: q
Out[8]: deque([2, 3444, 99])

In [9]: q.append(0)

In [10]: q
Out[10]: deque([2, 3444, 99, 0])
 

在队列两端插入或者删除元素时间复杂度都是O(1) , 而在列表的开头插入或者删除元素的时间复杂度为O(n)

3.匿名函数

关键字 lambda 表示匿名函数,冒号前的 x 表示函数参数

扫描二维码关注公众号,回复: 2763866 查看本文章

匿名函数有个限制 , 就是只能有一个表达式 , 不用写 return ,返回值就是该表达式的结果

匿名函数本身也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数

>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25

4.如何从一个集合中获得最小或者最大的N个元素 ?

(1)当要查找的元素个数相对比较小的时候,heapq 模块 的nlargest() 和 nsmallest() 是很合适的.

(2) 如果你仅仅想查找唯一的最小或最大(N=1)的元素的话,那么使用 min() 和 max() 函数会更快些

(3) 如果 N 的大小和集合大小接近的时候,通常先排序这个集合然后再使用切片操作会更快点(sorted(items)[:N] 或者是 sorted(items)[-N:])

5.

类(class):

一种程序员自定义的类型。类定义创建了一个新的类对象。

类对象(class object):

包含程序员自定义类型的细节信息的对象。类对象可以被用于创建该类型的实例

定义一个矩形类,指定矩形的一个角(或者中心) 宽度 以及 长度 .

class Point:
    """Represents a point in 2-D space."""

class Rectangle:
    """Represents a rectangle.

    attributes: width, height, corner.
    """

文档中列出了属性: width height;corner 是一个 point 对象,代表左下角的那个点.

进行赋值

box = Rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0

Rectangle 是一个 类 .

表达式  box.corner.x 的意思是,前往 box 所引用的对象 (box本身是一个实例), 找到 corner 的属性 ; 然后前往corner所引用的对象,找到叫做 x 的属性.

复制

别名会降低程序的可读性, 因为一个地方的变动可能对另一个地方造成预料之外的影响.跟踪所有引用同一个对象的变量是非常困难的.

通常用复制对象的方法取代为对象起别名 .
浅复制

copy 模块拥有一个叫做copy的函数,可以复制任何对象.

>>> p1 = Point()
>>> p1.x = 3.0
>>> p1.y = 4.0

>>> import copy
>>> p2 = copy.copy(p1)

>>> print_point(p1)
(3, 4)
>>> print_point(p2)
(3, 4)
>>> p1 is p2
False
>>> p1 == p2
False

is 运算符用来判断两者是否为同一个对象,结果正如我们所料! 不过 == 的结果也是False,这是为什么呢 ? == 运算符默认检查的是对象的标示是否相同,而非对象的值是否相同.

深复制

copy 模块拥有一个叫做deepcopy的函数,可以复制任何对象.

>>> box2 = copy.copy(box)    # 其中box是一个 Rectangle 的实例
>>> box2 is box
False
>>> box2.corner is box.corner
True


>>> box3 = copy.deepcopy(box)
>>> box3 is box
False
>>> box3.corner is box.corner
False

你会发现,当使用浅复制的时候,它仅仅复制了Rectangle对象,但没有复制嵌套的Point对象.

  • 用 isinstance 来检查某个对象是不是某个类的实例
>>> isinstance(p,Point)
True
  • 用hasattr 来检查一个对象是否有某个属性
>>> hasattr(p,'x')
True


字典中的键映射多个值

怎样实现一个键对应多个值的字典 ? 

经典的是:一个字典就是一个键对应一个单值的映射.如果想要映射多个值,那么你就需要将这多个值放在另外的容器中,比如列表或者集合.

d = {
    'a': [1, 2, 3],
    'b': [4, 5]
}
e = {
    'a': {1, 2, 3},
    'b': {4, 5}
}

当然,根据自己的需要选择列表或者集合.

其实最方便的还是 使用 collections 中的defaultdict 来构造对应的字典.

from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)

但有一点你需要注意: defaultdict 会自动为将要访问的键(就算目前字典中没有这样的键)创建映射实体, 比如访问一个不存在的键,值是一个空的集合或者列表,具体是什么,取决于你自己传进去的是list 还是set

对比一下传统的和用defaultdict的初始化字典的区别 , 高下立判.

d = {}
for key , value in pairs:
    if key not in d:
        d[key] = []
    d[key].append(value)

d = defaultdict(list)
for key,value in pairs:
    d[key].append(value)


字典排序

为了能控制一个字典中元素的顺序,你可以使用 collections 模块中的 OrderedDict 类 . 它会在迭代操作的时候保持元素被插入时的顺序

from collections import OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"
for key in d:
print(key, d[key])


字典的运算

如何在数据字典中执行一些计算操作(比如求最小值/最大值/排序)等?

通常与zip () 函数一起使用 . 将字典的键与值翻转过来 (可以用sorted函数直接对数据进行排序).

prices = {
    'ACME': 45.23,
    'AAPL': 612.78,
    'IBM': 205.55,
    'HPQ': 37.20,
    'FB': 10.75
}
#一次性的查找到字典的最小值和其对应的键

min_price = min(zip(prices.values(), prices.keys()))
# min_price is (10.75, 'FB')

max_price = max(zip(prices.values(), prices.keys()))
# max_price is (612.78, 'AAPL')

#使用sorted 和 zip 来排序字典数据
prices_sorted = sorted(zip(prices.values(), prices.keys()))
# prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
#                   (45.23, 'ACME'), (205.55, 'IBM'),
#                   (612.78, 'AAPL')]

note : zip()函数创建的是一个只能访问一次的迭代器.



怎样在两个字典中寻找相同点(比如相同的键/相同的值) ? 

为了寻找两个字典的相同点 , 可以简单的在两字典的keys() 或者 items() 方法返回结果上执行集合操作

a = {
    'x' : 1,
    'y' : 2,
    'z' : 3
}
b = {
    'w' : 10,
    'x' : 11,
    'y' : 2
}

In [34]: a.keys() & b.keys()     # 交集
Out[34]: {'x', 'y'}

In [35]: a.keys() | b.keys()     # 并集
Out[35]: {'w', 'x', 'y', 'z'}

In [36]: a.items() & b.items()   # 交集
Out[36]: {('y', 2)}

加入你想以现有字典构造一个排除几个指定键的新字典 . 下面利用李彪推导来实现这样的要求 . 

# Make a new dictionary with certain keys removed
c = {key:a[key] for key in a.keys() - {'z', 'w'}}
# c is {'x': 1, 'y': 2}

note : 进行集合操作时,要用集合的数据结构 . 也就是 { } .

猜你喜欢

转载自blog.csdn.net/bingo_ShenWei/article/details/81070301
今日推荐