【问题标题】:python: replace elements in list with conditionalpython:用条件替换列表中的元素
【发布时间】:2015-12-18 09:57:23
【问题描述】:

我正在尝试使用 python 执行以下操作,但我有一个奇怪的行为。假设我有以下列表:

x = [5, 4, 3, 2, 1]

现在,我正在做类似的事情:

x[x >= 3] = 3

这给出了:

x = [5, 3, 3, 2, 1]

为什么只有第二个元素被改变?我期待:

[3, 3, 3, 2, 1]

【问题讨论】:

  • 为什么我收到错误TypeError: unorderable types: list() >= int()
  • @KevinGuan 你用的是python3,Luca用的是python2
  • @NightShadeQueen 那么,为什么 Python 3 不支持这个?
  • @KevinGuan:因为 Python 3 可以防止你犯 Luca 犯的错误,即将列表对象与整数进行比较。
  • 每天都会有人问这些问题。答案总是一个列表理解/过滤器,也许人们应该更好地搜索,或者需要一个粘性。我很惊讶每天两次对于同一件事的回答如此之多。

标签: python python-3.x python-2.7 list


【解决方案1】:

因为 Python 会将x>=3 评估为True,并且由于True 等于1,所以x 的第二个元素将被转换为3。

为此,您需要使用列表理解:

>>> [3 if i >=3 else i for i in x]
[3, 3, 3, 2, 1]

如果您想知道为什么x >= 3 评估为 True,请参阅以下documentation

CPython 实现细节:除数字外的不同类型的对象按其类型名称排序;不支持正确比较的相同类型的对象按其地址排序。

当然,在 python-2.x 和 CPython 实现中,列表总是大于整数类型。因为字符串大于列表:

>>> ''>[]
True

但是,在 Python-3.X 中,您不能将不可排序的类型一起比较,结果中会得到 TypeError

In [17]: '' > []
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-052e7eb2f6e9> in <module>()
----> 1 '' > []

TypeError: unorderable types: str() > list()

【讨论】:

    【解决方案2】:

    您可以将此语法与Numpy 一起使用:

    >>> import numpy as np
    >>> x = np.array([5, 4, 3, 2, 1])
    >>> x[x>3]=3
    >>> x
    array([3, 3, 3, 2, 1])
    

    您也可以使用Pandas

    >>> import pandas as pd
    >>> x = pd.Series([5, 4, 3, 2, 1])
    >>> x
    0    5
    1    4
    2    3
    3    2
    4    1
    dtype: int64
    >>> x[x>3]=3
    >>> x
    0    3
    1    3
    2    3
    3    2
    4    1
    dtype: int64
    

    【讨论】:

    【解决方案3】:

    您正在使用 python 列表。在 python(2.x) 中,listint 的比较将比较 类型,而不是值。因此,您的比较结果为True,它等同于1。换句话说,你的表达式相当于:

    x[1] = 3  # x[1] == x[True] == x[x > 3]
    

    注意,python3.x 不允许这种类型的比较(因为它几乎肯定不是你的意思)——如果你想做这种操作,你几乎肯定会通过查看 numpy 文档想到它因为 numpy API 是专门为支持这种事情而设计的:

    import numpy as np
    array = np.arange(5)
    array[array > 3] = 3
    

    【讨论】:

    • 请注意,数字是特殊大小写的,始终排在其他类型之前。
    • @MartijnPieters -- 嗯......那是 CPython。 IIRC,其他实现可以定义他们想要的任何排序顺序——只要它是一致的。
    • 老实说更喜欢列表理解。少一个要导入的库:)
    • @mgilson:当然,这甚至可能意味着它们按id(type(obj)) 排序。但大多数实现都希望与 Python 2.x 保持一致并重新实现该行为。
    • @akalikin -- 这很公平。如果这是代码中唯一的地方,您将在其中执行此类操作,那么导入/学习 numpy 的开销可能不值得。但是,在我看来,这种操作很少会在代码中只出现一次——此时使用numpy 可能是一个巨大的优势。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 2015-12-29
    • 2017-08-02
    • 2019-01-17
    相关资源
    最近更新 更多