python:用条件替换列表中的元素

Luc*_*uca 4 python list python-2.7 python-3.x

我试图用python做以下事情并且有一个奇怪的行为.说我有以下列表:

x = [5, 4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

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

x[x >= 3] = 3
Run Code Online (Sandbox Code Playgroud)

这给出了:

x = [5, 3, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

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

[3, 3, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

Kas*_*mvd 9

因为Python将评估x>=3as True和since True等于1所以第二个元素x将被转换为3.

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

>>> [3 if i >=3 else i for i in x]
[3, 3, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

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

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

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

>>> ''>[]
True
Run Code Online (Sandbox Code Playgroud)

但是,在Python-3.X中,您无法将不可共享的类型进行比较,您将获得TypeError结果.

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

TypeError: unorderable types: str() > list()
Run Code Online (Sandbox Code Playgroud)


mgi*_*son 5

您正在使用python列表。在python(2.x)中,将a list与an int比较将比较类型,而不是值。因此,您的比较结果True等于1。换句话说,您的表达式等同于:

x[1] = 3  # x[1] == x[True] == x[x > 3]
Run Code Online (Sandbox Code Playgroud)

请注意,python3.x不允许进行这种类型的比较(因为它几乎肯定不是您的意思)–并且,如果您想执行这种操作,则可以肯定地通过查看numpy文档来考虑它,因为numpy API已经专为支持这种事情而设计:

import numpy as np
array = np.arange(5)
array[array > 3] = 3
Run Code Online (Sandbox Code Playgroud)


daw*_*awg 5

您可以在Numpy中使用以下语法:

>>> import numpy as np
>>> x = np.array([5, 4, 3, 2, 1])
>>> x[x>3]=3
>>> x
array([3, 3, 3, 2, 1])
Run Code Online (Sandbox Code Playgroud)

您也可以使用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
Run Code Online (Sandbox Code Playgroud)