Python itertools.groupby

本文介绍Python标准库itertools中的groupby函数用法,包括如何利用itemgetter和自定义函数进行分组,以及确保分组正确性的排序技巧。

Python itertools.groupby

groupby()把迭代器中相邻的,指定特征重复的元素挑出来放在一起

list中:key相同的dict元素

  • 通常使用itemgetter()参数规定分组依据
  • 也可编写简单的lambda函数传入key参数,作为分组依据(key参数必须传入函数)
from operator import itemgetter #itemgetter用来取dict中的key,省去了使用lambda函数
from itertools import groupby
d1={'name':'zhangsan','age':20,'country':'China'}
d2={'name':'wangwu','age':19,'country':'USA'}
d3={'name':'lisi','age':22,'country':'JP'}
d4={'name':'zhaoliu','age':22,'country':'USA'}
d5={'name':'pengqi','age':22,'country':'USA'}
d6={'name':'lijiu','age':22,'country':'China'}
lst=[d1,d2,d3,d4,d5,d6]

lst.sort(key=itemgetter('country')) #先排序,再进行groupby。lst排序后自身被改变
lstg = groupby(lst,itemgetter('country')) 
#lstg = groupby(lst,key=lambda x:x['country']) 等同于使用itemgetter()

for key,group in lstg:
    print(key,list(group))

#返回:
China [{'name': 'zhangsan', 'age': 20, 'country': 'China'}, {'name': 'lijiu', 'age': 22, 'country': 'China'}]
JP [{'name': 'lisi', 'age': 22, 'country': 'JP'}]
USA [{'name': 'wangwu', 'age': 19, 'country': 'USA'}, {'name': 'zhaoliu', 'age': 22, 'country': 'USA'}, {'name': 'pengqi', 'age': 22, 'country': 'USA'}]

自定义分组

  • 当对groupby()传入key参数,实际上挑选规则通过此函数完成。只要作用于函数的两个相邻元素返回的值相等,这两个元素就被认为在一组,函数返回值作为key。
import itertools

def height_class(h):
    if h>180:
        return 'tall'
    elif h<160:
        return 'short'
    else:
        return 'middle'

friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]

for m,n in itertools.groupby(friends,key = height_class):
    print(m,list(n))

#返回:
tall [191]
short [158, 159]
middle [165, 170, 177]
tall [181, 182, 190]

由于191与181,182,190不相邻,因此分组结果不在一组。

  • 欲使所有相同key的元素在一组中,要在list传入groupby()之前进行排序
import itertools

def height_class(h):
    if h>180:
        return 'tall'
    elif h<160:
        return 'short'
    else:
        return 'middle'

friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]

friends = sorted(friends,key = height_class)

for m,n in itertools.groupby(friends,key = height_class):
    print(m,list(n))

#返回:
middle [165, 170, 177]
short [158, 159]
tall [191, 181, 182, 190]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值