1

我正在使用 Python 3.2.3,并且想从列表中的特定元素中找到最大的数字。同样重要的是,我保留了一些关于哪个元素是最大数字的知识,但我对这是如何发生的非常灵活。让我解释...

背景

我有以下列表:

the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']

在每三个列表元素中,前两个是对数据的描述性 - 即“订单 1”、“订单 2”、“订单 3”作为“订单”、“1”、...“订单”、“ 2', ... 'Order', '3', ... 一直到“Order 9”。这些不会改变,并提供每三个列表元素的来源或名称。

每三个列表元素中的第三个是相关信息。在此示例中,数字是 5... 18... 45... 2... 等等。我想从每三个元素中找到最大的数字。在这种情况下,最大的数字是 45。这些数字一直在变化;它们可以是从 0 到 100 [含] 的任何整数。

到目前为止我尝试过的

我尝试以两种方式使用 Python 的 max() 函数。首先,简单...

max(the_list)

...它提供“订单”作为最大值。对我的目标很失望。

所以我决定尝试制作一个新列表,仅由原始列表的第三个元素组成。像这样...

foo = (the_line[2], the_line[5], the_line[8], the_line[11], the_line[14], the_best_line[17], the_best_line[20], the_best_line[23], the_best_line[26])

max(foo)

...它提供“8”作为最大数字,第 15 个列表元素和第 5 个第三列表元素。这是一个数字,但不是最高数字 45 [在此示例中]。

我还涉足了一系列 if-else 语句,但都没有成功,而且我认为必须有一个更 Pythonic//优雅的方式。我承认我可能在这条路线上退出得太早了,和/或我的心态错误。

4

4 回答 4

7

像这样的东西应该工作:

>>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
>>> the_list[::3]
['Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order']
>>> the_list[2::3]
['5', '18', '45', '2', '8', '2', '1', '1', '1']
>>> max(int(num) for num in the_list[2::3])
45

我使用 Python 的切片符号3来获取从元素 #2(即 )开始的每三个(即)元素2,使用the_list[2::3].

然而,这本身是不够的,因为 的条目the_list是字符串,它们是按字典顺序排序的,而不是按数字排序的。这就是为什么我必须调用int(num)每个术语并传递max一个生成器表达式,这里的形式是“(someseq 中的一些元素)”。

您还说跟踪哪个元素最大很重要,我假设您的意思是您想要索引。给定最大值,很容易找到哪些元素拥有它(在一般情况下,它可能不是唯一的,毕竟)使用另一个搜索匹配它的元素,这可能是最简单的。或者,您可以将索引本身编码到max调用中:

>>> max((int(num), i) for i, num in enumerate(the_list[2::3]))
(45, 2)

它给出了最大值和三组索引,并且因为元组是按第一个元素排序的,然后是第二个,等等。这种方法也不能处理非唯一的最大值。

不过,老实说,我可能会首先像@astynax 那样重塑数据——感觉这个列表不应该是平的。

于 2012-06-24T17:38:10.713 回答
5
>>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
>>> items = zip(*[iter(the_list)] * 3)
>>> items
[('Order', '1', '5'), ('Order', '2', '18'), ('Order', '3', '45'), ('Order', '4', '2'),('Order', '5', '8'), ('Order', '6', '2'), ('Order', '7', '1'), ('Order', '8', '1'), ('Order', '9', '1')]    
>>> max(items, key=lambda x: int(x[2]))
('Order', '3', '45')
于 2012-06-24T17:43:25.740 回答
3
   >>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
   >>> max(map(int,the_list[2::3]))
    45

这里 3[2::3]代表 step,即在 '5' 之后它跳到 '18' 然后跳到 '45',依此类推,每次跳 3。step如果未提供,则默认值为1。所以,

>>> the_list[2::3]
['5', '18', '45', '2', '8', '2', '1', '1', '1']

map() 是一个函数,它将特定函数应用于可迭代对象的每个对象,在这种情况下是the_list[2::3]并且应用的函数是intmap()在 python 2.x 中返回一个列表,在 python 3.x 中返回一个映射对象。

于 2012-06-24T17:40:48.427 回答
0

你可以尝试类似的东西

my_max = max( [the_list[i] for i in range(len(the_list)) if (i+1)%3==0 ] )
于 2012-06-24T17:40:31.610 回答