【Python练习cookbook】序列高级操作

不管顺序的去重转为set即可

1.将序列中重复元素去除,并保持顺序

#如果序列items中的值是可哈希的
def dedupe(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)

 >>> a = [1, 5, 2, 1, 9, 1, 5, 10]
>>> list(dedupe(a))
[1, 5, 2, 9, 10]

写成函数形式是使程序更通用,如读文件去除重复行:

with open(somefile,'r') as f:
    for line in dedupe(f):
        ...
# 如果序列items中的值是不可哈希-这个更通用,也支持可哈希序列
def dedupe(items, key=None):
    seen = set()
    for item in items:
        val = item if key is None else key(item)
        if val not in seen:
            yield item
            seen.add(val)

>>> a = [ {'x':1, 'y':2}, {'x':1, 'y':3}, {'x':1, 'y':2}, {'x':2, 'y':4}]
>>> list(dedupe(a, key=lambda d: (d['x'],d['y'])))
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
>>> list(dedupe(a, key=lambda d: d['x']))
[{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]

其中,key是一个从不可哈希值转为可哈希值的函数,并按key()的返回值去重,若值已经可哈希,则令key=None

                                                                                                                                                                                                          

hashable -- 可哈希

一个对象的哈希值如果在其生命周期内绝不改变,就被称为 可哈希 (它需要具有 __hash__() 方法),并可以同其他对象进行比较(它需要具有 __eq__() 方法)。可哈希对象必须具有相同的哈希值比较结果才会相同。

可哈希性使得对象能够作为字典键或集合成员使用,因为这些数据结构要在内部使用哈希值。

大多数 Python 中的不可变内置对象都是可哈希的;可变容器(例如列表或字典)都不可哈希;不可变容器(例如元组和 frozenset)仅当它们的元素均为可哈希时才是可哈希的。 用户定义类的实例对象默认是可哈希的。 它们在比较时一定不相同(除非是与自己比较),它们的哈希值的生成是基于它们的 id()

List

 x = [1,2,3]
 y = {x: 9}#生成字典y报错
  Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: unhashable type: 'list'

Tuple

z = (5,6)
y = {z: 89}
print(y)
{(5, 6): 89}

 

                                                                                                                                                                                                          

yield详解:

https://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html

https://www.jianshu.com/p/d09778f4e055

https://blog.csdn.net/dcrmg/article/details/78128041 


def func(n):
    for i in range(0,n):
        val = yield i #若不调用send,则val值总为None        
        print val
 
f = func(10)
f.next()
f.send(2)
f.send(10)
print f.next()

 

                                                                                                                                                                                                          

with...as语句:

https://www.jianshu.com/p/c00df845323c 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值