当前位置: 首页 > 科技观察

如何对Python字典数组进行去重?

时间:2023-03-15 08:19:32 科技观察

你知道吗?如果数组是由字典组成的,如果直接用set去重数组中的字典,会报错:test=[{"a":1},{"a":1},{"a":3},{"b":4}]test=list(set(test))>>>TypeError:unhashabletype:'dict'因为使用set去重的前提是对象是不可变对象,而字典是一个可变对象,所以不能直接用这个方法去重。那么如何解决这个问题呢?有三种方法。1.使用reduce方法reduce()函数会将参数序列中的元素累加起来。例如:fromfunctoolsimportreducedefadd(x,y):#两个数相加returnx+yprint(reduce(add,[1,2,3,4,5]))#计算列表总和:1+2+3+4+5#15上面的写法也可以通过lambda函数来简化:fromfunctoolsimportreduceprint(reduce(lambdax,y:x+y,[1,2,3,4,5]))#使用lambda匿名函数#15因此,我们写一个函数来对数组中的字典进行去重:fromfunctoolsimportreducedata=[{"a":1},{"a":1},{"a":3},{"b":4}]result=[]defunduplicate(result,data):如果数据不在结果中:result=result+[data]returnresultforiindata:result=unduplicate(result,i)print(result)#[{'a':1},{'a':3},{'b':4}]有点复杂,如果使用reduce函数和lambda函数,代码可以简化很多:defdelete_duplicate(数据):func=lambdax,y:x+[y]如果y不在xelsexdata=reduce(func,[[],]+data)returndataprint(delete_duplicate(data))#[{'a':1},{'a':3},{'b':4}]当然我也可以写成t他一行的函数:data=reduce(lambdax,y:x+[y]ifynotinxelsex,[[],]+data)只是可能在工作站被打死,所以不是建议这样做。2.奇怪的技巧文章开头提到,字典之所以不能用set去重,是因为它是一个可变对象。但是……如果我们把它变成一个不可变的对象呢?data=[{"a":1},{"a":1},{"a":3},{"b":4}]defdelete_duplicate(data):immutable_dict=set([str(item)foritemindata])data=[eval(i)foriinimmutable_dict]returndataprint(delete_duplicate(data))#[{'a':1},{'a':3},{'b':4}]是的,它有效。遍历字典,将每个子项转成字符串存入数组,然后使用set函数去重。通过eval函数,将去重数组中的每个子项转换回字典。那么Python,怎么能不好玩呢?高效方式上面提到了两种show操作,但是在实际工作中不推荐使用。一个原因是实在是太撒娇了,怕被打趴在办公桌上。另一个原因是它们在处理大数据量时表现不佳。下面是最正统的方式:data=[dict(t)fortinset([tuple(d.items())fordindata])]#data:#[{'a':1},{'b':2}]其实和第二种方法一样,就是把数组中的每一个字典都转成一个元组,也就是一个不可变对象,然后用set去重。去重后,使用dict函数将元组重组为字典对。但是这种方法不适用于字典中字典的数据结构,所以对于字典中字典的去重,例如:data2=[{"a":{"b":"c"}},{"a":{"b":"c"}}]在这种情况下,我建议使用第二种方法去重:data2=[{"a":{"b":"c"}},{"a":{"b":"c"}}]defdelete_duplicate_str(data):immutable_dict=set([str(item)foritemindata])data=[eval(i)foriinimmutable_dict]returndataprint(delete_duplicate_str(data2))#[{'a':{'b':'c'}}]怎么样,三种方法你都学会了吗?本文转载自微信公众号《Python实战宝典》,可通过以下二维码关注。转载本文请联系Python实战宝典公众号。