在python中通过键减少

mgo*_*ser 7 python reduce

我正在尝试通过python中最有效的方式来思考.

假设我有一个元组列表:

[('dog',12,2), ('cat',15,1), ('dog',11,1), ('cat',15,2), ('dog',10,3), ('cat',16,3)]
Run Code Online (Sandbox Code Playgroud)

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

def my_reduce(obj1, obj2):
    return (obj1[0],max(obj1[1],obj2[1]),min(obj1[2],obj2[2]))
Run Code Online (Sandbox Code Playgroud)

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

[('dog',12,1), ('cat',16,1)]
Run Code Online (Sandbox Code Playgroud)

Anz*_*zel 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
Run Code Online (Sandbox Code Playgroud)

要获得原始格式:

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


wim*_*wim 7

我不认为这reduce是一个很好的工具,因为你必须首先使用itertools或类似的方法按键对列表进行分组.否则你将会比较cats,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)
Run Code Online (Sandbox Code Playgroud)

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

>>> output = [(k,) + v for k, v in output.items()]
>>> output
[('dog', 12, 1), ('cat', 15, 1)]
Run Code Online (Sandbox Code Playgroud)

请注意,这将破坏原始列表中的排序.如果要保留键首先出现的顺序,请用输入法初始化输出OrderedDict.


Ste*_*ann 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]))
Run Code Online (Sandbox Code Playgroud)

解:

print [reduce(my_reduce, group)
       for _, group in groupby(sorted(pets), key=itemgetter(0))]
Run Code Online (Sandbox Code Playgroud)

输出:

[('cat', 16, 1), ('dog', 12, 1)]
Run Code Online (Sandbox Code Playgroud)