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)
因为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)
您正在使用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)
您可以在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)