Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据嵌套列表中内部列表的第一个元素获取所有最小元素?_Python_List_Minimum - Fatal编程技术网

Python 如何根据嵌套列表中内部列表的第一个元素获取所有最小元素?

Python 如何根据嵌套列表中内部列表的第一个元素获取所有最小元素?,python,list,minimum,Python,List,Minimum,简单地说!这里有一个列表,上面写着LST=[[12,1],[23,2],[16,3],[12,4],[14,5],我想根据列表内部的第一个元素得到这个列表的所有最小元素。因此,对于上述示例,答案是[12,1]和[12,4]。python中有什么典型的方法可以做到这一点吗? 提前感谢您。两张通行证: m = min(LST, key=operator.itemgetter(0))[0] print [x for x in LST if x[0] == m] minval = min(LST)[0

简单地说!这里有一个列表,上面写着
LST=[[12,1],[23,2],[16,3],[12,4],[14,5]
,我想根据列表内部的第一个元素得到这个列表的所有最小元素。因此,对于上述示例,答案是
[12,1]
[12,4]
。python中有什么典型的方法可以做到这一点吗? 提前感谢您。

两张通行证:

m = min(LST, key=operator.itemgetter(0))[0]
print [x for x in LST if x[0] == m]
minval = min(LST)[0]
return [x for x in LST if x[0] == minval]
一次通行证:

def all_minima(iterable, key=None):
  if key is None: key = id
  hasminvalue = False
  minvalue = None
  minlist = []
  for entry in iterable:
     value = key(entry)
     if not hasminvalue or value < minvalue:
        minvalue = value
        hasminvalue = True
        minlist = [entry]
     elif value == minvalue:
        minlist.append(entry)
  return minlist

from operator import itemgetter
return all_minima(LST, key=itemgetter(0))
def all_minima(iterable,key=None):
如果key为None:key=id
hasminvalue=False
最小值=无
minlist=[]
对于iterable中的条目:
值=键(条目)
如果不是hasminvalue或value
一个紧凑的单遍解决方案需要对列表进行排序——从技术上讲,这是
O(N log N)
对于一个
N
长的列表,但是Python的排序非常好,而且很多序列“恰好”在其中嵌入了某种顺序(这
timsort
巧妙地利用了这一点来加快速度),基于排序的解决方案有时在现实世界中具有令人惊讶的良好性能

以下是一个需要2.6或更高版本的解决方案:

import itertools
import operator
f = operator.itemgetter(0)

def minima(lol):
  return list(next(itertools.groupby(sorted(lol, key=f), key=f))[1])
要理解这种方法,“从内向外看”会有所帮助

f
,即
操作符。itemgetter(0)
,是一个关键函数,用于选择参数的第一项进行排序-
操作符的目的就是要轻松、紧凑地构建此类函数

sorted(lol,key=f)
因此返回列表的排序副本
lol
,按增加第一项排序。如果省略
key=f
,则排序后的副本将按字典顺序排列,因此也将按增加第一项的顺序排列,但这仅起“主键”的作用——具有相同第一子项的项将依次按其第二子项的值在它们之间排序,以此类推——当使用
key=f
时,保证在具有相同第一个子项的项目之间保持原始顺序。您没有指定您需要的行为(在您的示例中,这两种行为恰好产生相同的结果,因此我们无法与该示例区分),这就是为什么我会仔细详细说明这两种可能性,以便您可以选择

itertools.groupby(sorted(lol,key=f,key=f)
执行作为操作核心的“分组”任务:它根据
key
排序标准从序列中生成组(在本例中,序列
sorted
提供)。也就是说,当您调用
f
时,所有相邻项之间产生相同值的组(以该项为参数),然后是所有相邻项产生与第一个组不同值的组(但它们之间相同),依此类推
groupby
尊重它作为参数的序列的顺序,这就是为什么我们必须首先对
lol
进行排序(而
groupby
的这种行为使得它在序列顺序确实重要的许多情况下非常有用)

groupby
编辑的每个结果
yield
是一对
k,g
:一个键
k
,它是组中每个项目的
f(i)
结果,一个迭代器
g
,它按顺序生成组中的每个项目

给定迭代器的
next
内置(此解决方案中唯一需要Python2.6的部分)将生成其下一项——特别是在新生成的迭代器上调用时的第一项(当然,每个生成器都是迭代器,就像
groupby
的结果一样)。在早期的Python版本中,它必须是
groupby(…).next()
(因为
next
只是迭代器的一种方法,而不是内置的),它从2.6版开始就被弃用了

总之,我们的
next(…)
的结果正好是
k,g
对,其中
k
是第一个子项的最小值(即排序后的第一个值),而
g
是组项的迭代器

因此,使用该
[1]
我们只选择迭代器,因此我们有一个迭代器,只生成我们想要的子项

因为我们需要的是列表,而不是迭代器(根据您的规格),所以最外层的
list(…)
调用完成了任务


就性能而言,所有这些都值得吗?不在您给出的小示例列表中--
最小值实际上比@Kenny答案中的任一代码都慢(其中第一个“两通”解决方案更快)。我只是认为有必要记住您可能遇到的下一个序列处理问题的想法,其中典型输入的细节可能会有很大的不同(更长的列表、更少的极小值、输入中的偏序、&c、&c;-)。

这是一个常见的问题。请搜索。@SLott:你的链接问题与OP的问题完全不同。@KennyTM:怎么回事?他们看起来和我一模一样。我错过的区别是什么?@SLott:谢谢你指向链接。不幸的是,正如我所看到的,这是无关紧要的。
import itertools
import operator
f = operator.itemgetter(0)

def minima(lol):
  return list(next(itertools.groupby(sorted(lol, key=f), key=f))[1])