在python中通过键减少

时间:2015-04-29 02:15:23

标签: python reduce

我正在尝试通过最有效的方式在python中进行此操作。

假设我有一个元组列表:

[('dog',12,2), ('cat',15,1), ('dog',11,1), ('cat',15,2), ('dog',10,3), ('cat',16,3)]

假设我有一个函数,它接受这些元组中的两个并组合它们:

def my_reduce(obj1, obj2):
    return (obj1[0],max(obj1[1],obj2[1]),min(obj1[2],obj2[2]))

如何通过'key'执行有效的缩减,其中键可以是第一个值,因此最终结果将是:

[('dog',12,1), ('cat',16,1)]

4 个答案:

答案 0 :(得分:10)

或者,如果您安装了 pandas

import pandas as pd

l = [('dog',12,2), ('cat',15,1), ('dog',11,1), ('cat',15,2), ('dog',10,3), ('cat',16,3)]

pd.DataFrame(data=l, columns=['animal', 'm', 'n']).groupby('animal').agg({'m':'max', 'n':'min'})
Out[6]: 
         m  n
animal       
cat     16  1
dog     12  1

获取原始格式:

zip(df.index, *df.values.T) # df is the result above
Out[14]: [('cat', 16, 1), ('dog', 12, 1)]

答案 1 :(得分:7)

我认为describe('Test ', function () { beforeEach(module('myApp')); var $controller, testFactory, scope; // Initialize the controller and a mock scope beforeEach(inject(function(_$controller_, _$rootScope_, _testFactory_){ $controller = _$controller_; $rootScope = _$rootScope_; testFactory = _testFactory_; })); scope = $rootScope.$new(); describe('Initial test', function() { it('should return data', function() { var controller = $controller('testCtrl', {$scope:scope, testFactory:testFactory}); // expect something here }); }); }) 不是这项工作的好工具,因为您必须首先使用itertools或类似工具按键对列表进行分组。否则你将比较reducecats,所有地狱都会破裂!

相反,只需一个简单的循环即可:

dogs

然后,如果您想要原始格式:

>>> my_list = [('dog',12,2), ('cat',15,1), ('dog',11,1), ('cat',15,2)]
>>> output = {}
>>> for animal, high, low in my_list:
...     try:
...         prev_high, prev_low = output[animal]
...     except KeyError:
...         output[animal] = high, low
...     else:
...         output[animal] = max(prev_high, high), min(prev_low, low)

请注意,这会破坏原始列表中的排序。如果要保留键首次出现的顺序,请使用>>> output = [(k,) + v for k, v in output.items()] >>> output [('dog', 12, 1), ('cat', 15, 1)] 初始化输出。

答案 2 :(得分:5)

如果您想使用my_reducereduce,可以这样做。实际上它很短:

的制备:将

from itertools import groupby
from operator import itemgetter

pets = [('dog',12,2), ('cat',15,1), ('dog',11,1), ('cat',15,2), ('dog',10,3), ('cat',16,3)]

def my_reduce(obj1, obj2):
    return (obj1[0],max(obj1[1],obj2[1]),min(obj1[2],obj2[2]))

解决方案:

print [reduce(my_reduce, group)
       for _, group in groupby(sorted(pets), key=itemgetter(0))]

输出:

[('cat', 16, 1), ('dog', 12, 1)]

答案 3 :(得分:0)

如果你真的想使用reduce我认为这样可行(它会给你一个字典而不是列表但是meh)

&mut Write

我认为其他解决方案都更好