【问题标题】:Using max() on a list that contains numbers and strings在包含数字和字符串的列表上使用 max()
【发布时间】:2014-12-10 21:22:39
【问题描述】:

我有一个这样的列表:

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。 所以关键是要检索一个名称和一个与该名称关联的数字。有什么想法吗?

【问题讨论】:

  • 您为什么要使用列表来显示映射? self.thisdict = { 'Name': 13, 'Name1': 160, 'Name2': 394 }。然后name = max(self.thisdict, key=thisdict.get).
  • 我不知道,真的。我从未研究过python或任何语言,所以我不知道什么是执行什么功能的最佳方法。所以在这种情况下,我只是决定使用列表。另一个函数将名称和值附加到列表中,并且该函数正确读取它。它有效,这对我来说已经足够了。不过,我会查找映射。谢谢。

标签: python string list int max


【解决方案1】:

在 Python 2 中,您可以比较不同类型的值(然后它们将通过类型的名称进行比较。因为str 在@987654322 之后@,任何字符串都将比任何整数都高。由于这没有任何意义,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】:

    通过调用max,您要求它比较所有值。

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

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

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

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

    附带说明,使用这样的数据结构会使很多事情变得更加复杂。看来您在这里真正想要的不是交替名称和数字的列表,而是将名称映射到数字的字典,或者名称-数字对的列表,或类似的东西。然后你可以写出更具可读性的东西。例如,在此之后:

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

    ...您可以执行以下操作:

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

    【讨论】:

    • +1 为您的侧节点。让我希望我在发布我的答案之前试图弄清楚 OP 实际上试图用该代码做什么...... :-)
    • 谢谢,就这么简单。
    【解决方案3】:

    您需要首先从列表中过滤出字符串,因为不同类型的值具有任意(但一致)排序(在 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】:

      这是因为在 Python 2 中字符串总是比较大于整数。您可以使用自定义键函数来解决这个问题:

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

      【讨论】:

        【解决方案5】:

        我会这样做:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-02
          • 2020-11-11
          • 2017-07-04
          • 2018-12-18
          • 1970-01-01
          • 2021-08-12
          • 2021-02-27
          • 2013-08-04
          相关资源
          最近更新 更多