任何类似python-min的函数,其结果都是一个列表

任何类似python-min的函数,其结果都是一个列表,python,min,Python,Min,这里的min()只返回一个集合。它实际上应该返回: >>> lst [('BFD', 0), ('NORTHLANDER', 3), ('HP', 23), ('VOLT', 3)] >>> min([x for x in lst if x[1]!=0], key=lambda x: x[1]) ('NORTHLANDER', 3) >>> 有没有这样的内置函数?这是一个简单的两步解决方案,首先计算最小值,然后收集所有具有最小值的元组,因此

这里的min()只返回一个集合。它实际上应该返回:

>>> lst
[('BFD', 0), ('NORTHLANDER', 3), ('HP', 23), ('VOLT', 3)]
>>> min([x for x in lst if x[1]!=0], key=lambda x: x[1])
('NORTHLANDER', 3)
>>>

有没有这样的内置函数?

这是一个简单的两步解决方案,首先计算最小值,然后收集所有具有最小值的元组,因此编写您自己的函数来实现这一点。这是一个相当专门的操作,而不是通用的
min()
函数所期望的

查找具有最小值的元素:

[('NORTHLANDER', 3), ('VOLT', 3)]
然后只需形成一个新列表,从
list
中提取元素,其中值为
lstm

>>> lstm = min([x for x in lst if x[1] > 0], key = lambda x: x[1])
>>> lstm
('NORTHLANDER', 3)

这是一个简单的两步解决方案,首先计算最小值,然后收集所有具有最小值的元组,因此编写您自己的函数来实现这一点。这是一个相当专门的操作,而不是通用的
min()
函数所期望的

查找具有最小值的元素:

[('NORTHLANDER', 3), ('VOLT', 3)]
然后只需形成一个新列表,从
list
中提取元素,其中值为
lstm

>>> lstm = min([x for x in lst if x[1] > 0], key = lambda x: x[1])
>>> lstm
('NORTHLANDER', 3)
??它是为处理类似数据而设计的:

>>> [y for y in lst if y[1] == lstm[1]]
[('NORTHLANDER', 3), ('VOLT', 3)]
(这只是一个想法,不是为了提高效率)

?它是为处理类似数据而设计的:

>>> [y for y in lst if y[1] == lstm[1]]
[('NORTHLANDER', 3), ('VOLT', 3)]

(这只是一个想法,不是为了提高效率)

您可以编写自己的multimin函数,如下所示:

# Instantiate excluding zero length items
>>> c = collections.Counter({k: v for (k, v) in lst if v != 0})
>>> c
Counter({'HP': 23, 'NORTHLANDER': 3, 'VOLT': 3})

# Retrieve most common then reverse it
>>> least_common = c.most_common()[::-1]
[('VOLT', 3), ('NORTHLANDER', 3), ('HP', 23)]

>>> [(k,v) for (k,v) in least_common if v == least_common[0][1]]
[('VOLT', 3), ('NORTHLANDER', 3)]
例如:

def multimin(seq, key=None):
    if key is None:
        key = lambda x: x
    min_e = min(seq, key=key)
    return filter((lambda x: key(x) == key(min_e)), seq)

您可以编写自己的multimin函数,如下所示:

# Instantiate excluding zero length items
>>> c = collections.Counter({k: v for (k, v) in lst if v != 0})
>>> c
Counter({'HP': 23, 'NORTHLANDER': 3, 'VOLT': 3})

# Retrieve most common then reverse it
>>> least_common = c.most_common()[::-1]
[('VOLT', 3), ('NORTHLANDER', 3), ('HP', 23)]

>>> [(k,v) for (k,v) in least_common if v == least_common[0][1]]
[('VOLT', 3), ('NORTHLANDER', 3)]
例如:

def multimin(seq, key=None):
    if key is None:
        key = lambda x: x
    min_e = min(seq, key=key)
    return filter((lambda x: key(x) == key(min_e)), seq)

使用
集合.defaultdict

>>> lst = [('BFD', 0), ('NORTHLANDER', 3), ('HP', 23), ('VOLT', 3)]
>>> print multimin([x for x in lst if x[1]!=0], key=lambda x: x[1]) 
[('NORTHLANDER', 3), ('VOLT', 3)]
Out:

d=collections.defaultdict(list)
for item in lst:
    d[item[1]].append(item)
d[min(key for key in d.keys() if key!=0)]
测试

[('NORTHLANDER', 3), ('VOLT', 3)]
因此,
defaultdict
的速度似乎要快一倍多

编辑 @martineau优化:

#unwind's solution

def f(lst):
    return [y for y in lst if y[1] == min([x for x in lst if x[1] > 0],
                                             key = lambda x: x[1])[1]]

def f2(lst):
    d=collections.defaultdict(list)
    for item in lst:
        d[item[1]].append(item)
    return d[min(key for key in d.keys() if key!=0)]

%timeit f(lst)
100000 loops, best of 3: 12.1 us per loop
%timeit f2(lst)
100000 loops, best of 3: 5.42 us per loop
另一个基于
dict
的解决方案是使用
set。默认值甚至更快一些:

def f3(lst):
    lstm = min((x for x in lst if x[1]), key = lambda x: x[1])[1]
    return [y for y in lst if y[1] == lstm]

%timeit f3(lst)
100000 loops, best of 3: 4.19 us per loop

使用
集合.defaultdict

>>> lst = [('BFD', 0), ('NORTHLANDER', 3), ('HP', 23), ('VOLT', 3)]
>>> print multimin([x for x in lst if x[1]!=0], key=lambda x: x[1]) 
[('NORTHLANDER', 3), ('VOLT', 3)]
Out:

d=collections.defaultdict(list)
for item in lst:
    d[item[1]].append(item)
d[min(key for key in d.keys() if key!=0)]
测试

[('NORTHLANDER', 3), ('VOLT', 3)]
因此,
defaultdict
的速度似乎要快一倍多

编辑 @martineau优化:

#unwind's solution

def f(lst):
    return [y for y in lst if y[1] == min([x for x in lst if x[1] > 0],
                                             key = lambda x: x[1])[1]]

def f2(lst):
    d=collections.defaultdict(list)
    for item in lst:
        d[item[1]].append(item)
    return d[min(key for key in d.keys() if key!=0)]

%timeit f(lst)
100000 loops, best of 3: 12.1 us per loop
%timeit f2(lst)
100000 loops, best of 3: 5.42 us per loop
另一个基于
dict
的解决方案是使用
set。默认值甚至更快一些:

def f3(lst):
    lstm = min((x for x in lst if x[1]), key = lambda x: x[1])[1]
    return [y for y in lst if y[1] == lstm]

%timeit f3(lst)
100000 loops, best of 3: 4.19 us per loop

如果将
f()
更改为
lstm=min((如果x[1]),则在lst中x代表x,key=lambda x:x[1])[1]
后接
返回[y代表y,如果y[1]=lstm]
的速度大约是
默认dict
方法的两倍。@martineau--添加了您的优化和另一个基于dict的解决方案,速度甚至更快。啊,一个极好的补充。我可以把它做得更快,但是这里的注释中有太多的代码,所以请检查(和时间)版本。如果您将
f()
更改为
lstm=min((如果x[1]在lst中为x),key=lambda x:x[1])[1]
后跟
如果y[1]=lstm,则返回[y:y]
它的速度大约是您的
defaultdict
方法的两倍。@martineau——添加了您的优化和另一个基于dict的解决方案,速度甚至略快。啊,这是一个极好的补充。我可以把它做得更快,但它的代码太多,无法放在这里的注释中,所以请检查(和时间)版本。这可以通过使用
lstm=min((如果x[1]),key=lambda x:x[1])[1]
[y如果y[1]==lstm],使用
lstm=min略微优化((x代表lst中的x,如果x[1]),key=lambda x:x[1])[1]
[y代表lst中的y,如果y[1]==lstm]
。请看类似的问题FWIW@unwind的答案与接受的答案类似。请看类似的问题FWIW@unwind的答案与接受的答案类似。