python数据结构

6 篇文章 0 订阅
1 篇文章 0 订阅

下面是一些python中常见的数据结构知识点总结,还有一些编程小技巧分享给大家

字典元组列表等数据结构
  • 一个键对应单一的映射,若想一个键对应多个值,需要将多个值放入容器中,可以是列表或是集合
  • 若不关心元素的顺序,并且元素不重复的话,可以使用集合
  • 若在乎添加的顺序可使用列表
  • defaultdict模块

    • defaultdict模块可以在初始化时,就将key的类型固定,只需关注修改的一些操作即可

    • from collections import defaultdict
      
      d=defaultdict(list)
      d['a'].append('1')
      d['b'].append('2')
      
      d_=defaultdict(set)
      d_['a'].add('1')
      d_['b'].add('2')
      
      dct=defaultdict(list)
      pairs=['a','b','c','d']
      for key,value in paires:
          dct[key].append(value)
      return dct
      
      
      print(d)
      print(d_)
      
    • 使用defaultdict可以快速创建一个字典映射

  • OrderdeDIct模块

    from collections import OrderedDict
    def ordered_dict():
        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])
    ordered_dict()
    
    • OrderedDict函数可以保存字典的存入顺序,返回顺序字典
    • OrderedDict函数内部有一个双向链表,控制元素的插入顺序,当一个元素插入时,默认添加到尾部,对于一个存在的键的重复复置不会改变键的顺序
    • OrderedDict函数的创建对象比普通字典大两倍,因为内部链表的原因,所以当创建时,要权衡内存占用情况
  • 字典的运算

    prices = { 'ACME': 45.23,
              'AAPL': 612.78,
              'IBM': 205.55, 
              'HPQ': 37.20,
              'FB': 10.75
    }
    min_price=min(zip(prices.values(),prices.keys()))
    max_price=max(zip(prices.values(),prices.keys()))
    print(min_price,max_price)
    sort_dct=sorted(zip(prices.values(),prices.keys()))
    print(sort_dct)
    print(type(sort_dct))
    '''显示结果如下:
    (10.75, 'FB') (612.78, 'AAPL')
    [(10.75, 'FB'), (37.2, 'HPQ'), (45.23, 'ACME'), (205.55, 'IBM'), (612.78, 'AAPL')]
    <class 'list'>'''
    
    • 字典的运算取值(最大或最小)可使用zip函数进行
    • 可以使用sorted函数对字典进行排序
    • 当字典中出现不同的键对应相同的值时,会比较键的大小来返回结果
  • 比较字典

    a = {'x' : 1, 'y' : 2, 'z' : 3 }
    b = {'w' : 10, 'x' : 11, 'y' : 2 }
    # Find keys in common  交集
    a.keys() & b.keys() # { 'x', 'y' }
    # Find keys in a that are not in b  差集
    a.keys() - b.keys() # { 'z' }
    # Find (key,value) pairs in common  键值对交集
    a.items() & b.items() # { ('y', 2) }
    
    
    • 可以简单的使用集合操作符来比较两个字典键值对的异同点
    • 集合的键支持集合操作,若想对键集合执行一些几个操作可以先转换成set,同理值集合也一样
  • 删除序列相同元素并保持顺序

    def setone(item):
        seen=set()
        for element in item:
            if element not in seen:
                yield element
                seen.add(element)
    
    • 当序列中的元素可hasnable时,可以使用生成器和集合的方式实现

    当序列不可hashable时

    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}]'''
    
    
    • 需要先将序列转换为可hashable的再来过滤
  • 命名切片

    record='123456789012345678901234567890123456789012345678901234567890'
    SHARES = slice(20, 23)
    PRICE = slice(31, 37)
    cost = int(record[SHARES]) * float(record[PRICE])
    print(cost)
    
    items = [0, 1, 2, 3, 4, 5, 6]
    a=slice(2,4,2)
    print(type(a))
    print(items[a])
    print(a.start)
    print(a.stop)
    print(a.step)
    
    a=slice(5,50,2)
    s='HelloWorld'
    print(type(a.indices(len(s))))  #a.indices()函数返回元组对象(start,stop,step)三元组
    for i in range(*a.indices(len(s))):
        print(s[i])
    
    
    • slice函数创建切片对象,可以slice任何支持切片操作的对象
    • 可以调用slice函数创建的切片对象方法start,stop,step属性进一步查看相关信息
    • slice创建的对象方法indices可以划定边界长度,使创建的对象长度固定
  • 查找序列中出现次数最多的元素

    from collections import Counter
    
    words = [ 'look', 'into', 'my', 'eyes', 'look',
             'into', 'my', 'eyes', 'the', 'eyes',
             'the', 'eyes', 'the', 'eyes', 'not', 
             'around', 'the', 'eyes', "don't", 
             'look', 'around', 'the', 'eyes', 
             'look', 'into', 'my', 'eyes', "you're", 'under' ]
    word_counts = Counter(words)  #创建Counter对象
    top_three = word_counts.most_common(3)  #打印出现频率最高的三个单词,使用most_common()函数
    print(top_three)    # Outputs [('eyes', 8), ('the', 5), ('look', 4)]
    
    from collections import Counter
    
    words = [ 'look', 'into', 'my', 'eyes', 'look',
             'into', 'my', 'eyes', 'the', 'eyes',
             'the', 'eyes', 'the', 'eyes', 'not', 
             'around', 'the', 'eyes', "don't", 
             'look', 'around', 'the', 'eyes', 
             'look', 'into', 'my', 'eyes', "you're", 'under' ]
    morewords = ['why','are','you','not','looking','in','my','eyes']
    a=Counter(words)
    b=Counter(morewords)
    c=a+b
    print(len(c))
    d=a-b
    print(d)
    
    
    • most_common()函数返回出现次数最多的元素
    • Counter的对象可以直接进行数学运算操作
  • 通过某个关键词排序字典列表

    from operator import itemgetter
    
    rows = [ {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
    {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
    {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
    {'fname': 'Big', 'lname': 'Jones', 'uid': 1004} ]
    
    rows_by_lname=sorted(rows,key=itemgetter('lname'))
    rows_by_uid=sorted(rows,key=itemgetter('uid'))  #itemgetter函数可添加多个参数itemgetter('fname','lname')
    rows_by_fname = sorted(rows, key=lambda r: r['fname'])
    rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
    min(rows, key=itemgetter('uid'))
    max(rows, key=itemgetter('uid'))
    
    print(rows_by_uid)
    print(rows_by_lname)
    
    • operator模块的函数itemgtter()可以实现按照某个字典键排序字典列表
    • itemgetter可以使用lambda函数替换,但是itemgetter函数运行更快
    • 如果数据较少,且要返回单一最值,可使用max和min函数
  • 排序不支持原生对象的解决

    class User():
        def __init__(self,user_id):
            self.user_id=user_id
            
        def __repr__(self):
            return f'User({self.user_id})'
        
    def sort_one():
        users=[User(32),User(12),User(50)]
        user_sort=sorted(users,key=lambda u:u.user_id)
        return user_sort
    
    #——————————————————————————————
    from operator import attrgetter
    sorted(users, key=attrgetter('user_id'))
    by_name = sorted(users, key=attrgetter('last_name', 'first_name'))
    min(users, key=attrgetter('user_id')
    max(users, key=attrgetter('user_id')
    
    • sorted()函数的key参数,接受一个callable对象,callable对象返回其中的值,sorted函数根据返回的值对序列进行排序
    • 还可以使用attrgetter模块,接受排序依据参数,进行序列的排序
    • attrgetter要比lambda函数稍微快一些,且可以支持多个参数
    • attrgetter同样适用于max和min函数
  • 通过某个字段为记录分组

    from operator import itemgetter
    from itertools import groupby
    
    rows = [ {'address': '5412 N CLARK', 'date': '07/01/2012'},
            {'address': '5148 N CLARK', 'date': '07/04/2012'},
            {'address': '5800 E 58TH', 'date': '07/02/2012'},
            {'address': '2122 N CLARK', 'date': '07/03/2012'},
            {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
            {'address': '1060 W ADDISON', 'date': '07/02/2012'},
            {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
            {'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
           ]
    rows.sort(key=itemgetter('date'))
    
    for date,item in groupby(rows,key=itemgetter('date')):
        print(date)
        for i in item:
            print(i)
            
    from collections import defaultdict
    rows_by_date = defaultdict(list)
    for row in rows:
        rows_by_date[row['date']].append(row)
    
    for r in rows_by_date['07/01/2012']:
        print(r)
    '''显示结果如下:
    07/01/2012
    {'address': '5412 N CLARK', 'date': '07/01/2012'}
    {'address': '4801 N BROADWAY', 'date': '07/01/2012'}
    07/02/2012
    {'address': '5800 E 58TH', 'date': '07/02/2012'}
    {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}
    {'address': '1060 W ADDISON', 'date': '07/02/2012'}
    07/03/2012
    {'address': '2122 N CLARK', 'date': '07/03/2012'}
    07/04/2012
    {'address': '5148 N CLARK', 'date': '07/04/2012'}
    {'address': '1039 W GRANVILLE', 'date': '07/04/2012'}'''
    
    • itertools中的groupby可以根据传进来的key参数,分组排序
    • groupby函数扫描整个序列并查找相同连续值返回一个对象和迭代器,注意迭代器返回的是上述传进参数的键有着相同的值的所有对象元素集合
    • 若只想将某个字段放进新的数据结构中,可使用defauledict,若不关心排序问题,运行的比先排序后groupby快一些
  • 过滤(除了使用列表推导,生成器表达式)

    values = ['1', '2', '-3', '-', '4', 'N/A', '5']
    def is_int(val):
        try:
            x = int(val)
            return True
        except ValueError:
            return False
    ivals = list(filter(is_int, values))
    print(ivals)
    
    from itertools import compress
    
    addresses = [ '5412 N CLARK',
                 '5148 N CLARK', 
                 '5800 E 58TH', 
                 '2122 N CLARK' ,
                 '5645 N RAVENSWOOD',
                 '1060 W ADDISON', 
                 '4801 N BROADWAY',
                 '1039 W GRANVILLE',
                ]
    count=[3,4,5,2,5,6,7]
    more=[n>5 for n in count]
    new=list(compress(addresses,more))
    print(new)
    
    • 使用filter函数可以处理复杂情况的过滤
    • 使用推导式的时候,可以将过滤掉的元素更改,或将筛选出的元素更改,通过增加控制条件即可
    • 使用compress函数:首先需要一个Boolean序列对象,再将需要过滤的元素放进,按位置的True,False过滤出True的序列对象
    • compress函数返回的是一个迭代器对象,可以做进一步转换
  • namedtuple的实例参数的替换

    from collections import namedtuple
    Stock = namedtuple('Stock', ['name', 'shares', 'price', 'date', 'time'])
    stock_prototype = Stock('', 0, 0.0, None, None) # Create a prototype instance 
    
    def dict_to_stock(s):  # Function to convert a dictionary to a Stock
        return stock_prototype._replace(**s)  #接受一个字典
    
    a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
    b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '12/17/2012'}
    print(dict_to_stock(a))
    print(dict_to_stock(b))
    
    • _replace方法替换创建的命名元组实例的属性
    • 若想在刚创建时,预留一些参数不设定即可使用此方法,再使用replace方法替换即可
  • 合并多个字典

    • 使用ChainMap模块

    • from collections import ChainMap
      a = {'x': 1, 'z': 3 } b = {'y': 2, 'z': 4 }
      c = ChainMap(a,b)
      
      print(c['x']) # Outputs 1 (from a)
      print(c['y']) # Outputs 2 (from b)
      print(c['z']) # Outputs 3 (from a)
      
      merged = dict(b)
      merged.update(a)
      print(merged)
                    
      
      • ChainMap接受字典参数并在其内部创建一个包含字典的列表,并重新定义了一些字典操作来遍历列表,大部分的字典操作都是支持的
      • 若在ChainMap中出现相同的键时,键的值和第一个字典中的键的值一致
      • 对于ChainMap创建的实例对象的修改操作,会影响到第一个合并的字典的内容
      • update函数也是合并字典,若两个字典中有相同的键,则更新键值,对原字典的操作,不会影响到合并的字典的内容
      • 注意对于ChainMap生成的字典,若对原字典进行修改,则会影响到合并的字典,因为ChainMap不会创建新的字典

好啦这就是关于python中的数据结构的一些方法与属性的阐述啦!希望对大家有所帮助

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯吶psycho

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

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

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

打赏作者

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

抵扣说明:

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

余额充值