在包含数字和字符串的列表上使用max()

时间:2014-10-15 17:37:41

标签: python string list int max

我有一个这样的列表:

self.thislist = ['Name', 13, 'Name1', 160, 'Name2', 394]

基本上,列表后面有一个名称和一个数字,我试图找出列表中的最高数字,即394。但出于某种原因,它选择的名称为this

      if max(self.thislist) > 150:
            this = max(self.thislist) # so this should be 394
            position = self.thislist.index(this) # The index of it
            temponary = position - 1 # This is so we can find the name that is associated with it
            name = self.thislist[temponary] #and this retrieves the name

并且它检索例如'Name',它应该是394。 因此,重点是检索与该名称相关联的名称和数字。有什么想法吗?

5 个答案:

答案 0 :(得分:5)

致电max,您要求它比较所有值。

在Python 2.x中,大多数值可以相互比较,即使它们是不同类型的;比较在某些任意和特定于实现的方式中是有意义的(在CPython中,它主要归结为比较类型对象本身的名称),但这对您来说很少有用。

在Python 3.x中,大多数不相关类型的值无法相互比较,因此您只需获得TypeError而不是无用的答案。但解决方案是一样的。

如果要比较数字并忽略名称,可以过滤掉所有非数字,跳过每个偶数元素,使用key函数将所有非数字转换为小于任意数字的数字,或几乎任何其他避免尝试比较名称和数字的东西。例如:

if max(self.thislist[1::2]) > 150:

作为旁注,使用这样的数据结构会使很多事情变得更复杂。看起来你真正想要的不是一个交替的名字和数字的列表,而是一个将名称映射到数字的dict,或者名称 - 数字对的列表,或类似的东西。然后你可以更容易地写东西。例如,在此之后:

self.thisdict = dict(zip(self.thislist[::2], self.thislist[1::2]))

...你可以做以下事情:

if max(self.thisdict.itervalues()) > 150:

答案 1 :(得分:3)

在Python 2中,您可以比较不同类型的值(然后它们将通过该类型的名称进行比较。由于str来自int,任何字符串都将比任何整数都高。由于这没有任何意义,Python 3明智地删除了这个特性)

为了获得您想要的内容,请使用自定义key

>>> thislist = ['Name', 13, 'Name1', 160, 'Name2', 394]
>>> max(thislist, key =  lambda x: x if isinstance(x, (int, long, float)) else 0)
394

(这假设列表中至少有一个正数)

答案 2 :(得分:2)

那是因为字符串总是比Python 2中的整数大。你可以使用自定义键功能来解决这个问题:

>>> lst = ['Name', 13, 'Name1', 160, 'Name2', 394]
>>> max(lst, key=lambda x: (isinstance(x, (int, float)), x))
394

答案 3 :(得分:1)

您希望首先从列表中过滤掉字符串,因为不同类型的值具有任意(但一致)排序(在python2.x中),因为可以轻松检查:

>>> 'foo' > 1
True

我只是使用生成器表达式进行过滤,该表达式只会提取数字并将其传递给max

import numbers
max(x for x in self.thislist if isinstance(x, numbers.Number))

演示:

>>> lst = ['foo', 1, 1.6, 'bar']
>>> max(x for x in lst if isinstance(x, numbers.Number))
1.6
>>> lst = ['foo', 1, 1.6, 2, 'bar']
>>> max(x for x in lst if isinstance(x, numbers.Number))
2

答案 4 :(得分:1)

我会这样做:

>>> thislist = ['Name', 13, 'Name1', 160, 'Name2', 394]
>>> names, numbers = thislist[0::2], thislist[1::2]
>>> max(zip(numbers, names))
(394, 'Name2')