abe*_*ger 84 python numpy python-2.7
我遇到了一些代码类似的代码
x[x<2]=0
Run Code Online (Sandbox Code Playgroud)
玩弄各种变化,我仍然坚持这种语法的作用.
例子:
>>> x = [1,2,3,4,5]
>>> x[x<2]
1
>>> x[x<3]
1
>>> x[x>2]
2
>>> x[x<2]=0
>>> x
[0, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
tra*_*t0r 118
这只适用于NumPy数组.列表的行为是无用的,并且特定于Python 2(不是Python 3).您可能需要仔细检查原始对象是否确实是NumPy数组(请参见下文)而不是列表.
但是在这里的代码中,x是一个简单的列表.
以来
x < 2
Run Code Online (Sandbox Code Playgroud)
因此,是假,即0
x[x<2] 是 x[0]
x[0] 变了.
相反,x[x>2]是x[True]或x[1]
所以,x[1]改变了.
为什么会这样?
比较规则是:
当您订购两个字符串或两个数字类型时,排序以预期的方式完成(字符串的字典顺序,整数的数字排序).
当您订购数字和非数字类型时,数字类型首先出现.
当您订购两个不兼容的类型(两者都不是数字)时,它们按其类型名的字母顺序排序:
所以,我们有以下顺序
numeric <list <string <元组
请参阅Python的比较字符串和int的接受答案?.
如果x是NumPy数组,那么由于布尔数组索引,语法更有意义.在这种情况下,x < 2根本不是布尔值; 它是一个布尔数组,表示每个元素是否x小于2. x[x < 2] = 0然后选择小于2 的元素x并将这些单元格设置为0.请参阅索引.
>>> x = np.array([1., -1., -2., 3])
>>> x < 0
array([False, True, True, False], dtype=bool)
>>> x[x < 0] += 20 # All elements < 0 get increased by 20
>>> x
array([ 1., 19., 18., 3.]) # Only elements < 0 are affected
Run Code Online (Sandbox Code Playgroud)
Kar*_*ath 45
>>> x = [1,2,3,4,5]
>>> x<2
False
>>> x[False]
1
>>> x[True]
2
Run Code Online (Sandbox Code Playgroud)
bool简单地转换为整数.索引为0或1.
Ant*_*ala 14
在你的问题的原代码只能在Python 2.如果x是list在Python 2中,比较x < y是False,如果y是int埃格尔.这是因为将列表与整数进行比较是没有意义的.但是在Python 2中,如果操作数不具有可比性,则比较基于CPython对类型名称的字母顺序进行排序 ; 此外,所有数字首先出现在混合型比较中.这甚至没有在CPython 2的文档中详细说明,并且不同的Python 2实现可能会给出不同的结果.这是[1, 2, 3, 4, 5] < 2计算结果为False,因为2是一个数字,因此多了一个"小" list的CPython的.这种混合比较最终被认为是一个过于模糊的特征,并在Python 3.0中被删除.
现在,结果<是bool; 并且bool是一个子类的int:
>>> isinstance(False, int)
True
>>> isinstance(True, int)
True
>>> False == 0
True
>>> True == 1
True
>>> False + 5
5
>>> True + 5
6
Run Code Online (Sandbox Code Playgroud)
所以基本上你取的是0或1元素,这取决于比较是真还是假.
如果您尝试了上述在Python 3的代码,你会得到TypeError: unorderable types: list() < int()由于在Python 3.0的变化:
订购比较
Python 3.0简化了订购比较的规则:
排序比较操作符(
<,<=,>=,>)提出一个TypeError例外,当操作数没有意义的自然顺序.因此,这样的表达式1 < '',0 > None或者len <= len不再有效,并且如None < None提高TypeError,而不是返回False.一个必然结果是,对异构列表进行排序不再有意义 - 所有元素必须相互比较.请注意,这不适用于==和!=运算符:不同无比类型的对象总是相互比较不相等.
有许多数据类型会使比较运算符超载以执行不同的操作(来自pandas,numpy的数组的数据帧).如果您使用的代码执行了其他操作,那是因为x它不是alist,而是一个其他类的实例,其中运算符<被覆盖以返回不是a的值bool; 然后这个值特别由x[](aka __getitem__/ __setitem__)处理
这还有一个用途:代码高尔夫.Code golf是编写程序的艺术,可以在尽可能少的源代码字节中解决一些问题.
return(a,b)[c<d]
Run Code Online (Sandbox Code Playgroud)
大致相当于
if c < d:
return b
else:
return a
Run Code Online (Sandbox Code Playgroud)
除了a和b都在第一个版本中评估,但在第二个版本中没有.
c<d评估为True或False.
(a, b)是一个元组.
对元组进行索引就像在列表上建立索引一样:(3,5)[1]== 5.
True等于1并False等于0.
(a,b)[c<d](a,b)[True](a,b)[1]b或者False:
(a,b)[c<d](a,b)[False](a,b)[0]a在堆栈交换网络上有一个很好的列表,您可以对python执行许多令人讨厌的事情,以节省几个字节.https://codegolf.stackexchange.com/questions/54/tips-for-golfing-in-python
虽然在普通代码中不应该使用它,但在你的情况下,这意味着x它既可以作为可以与整数进行比较的东西,也可以作为支持切片的容器,这是一种非常不寻常的组合.正如其他人所指出的那样,这可能是Numpy代码.
一般来说它可能意味着什么.这是已经解释这是什么意思,如果x是list或numpy.ndarray,但一般只取决于如何比较运算符(<,>,...),以及如何获取/设置项([...]-syntax)来实现.
x.__getitem__(x.__lt__(2)) # this is what x[x < 2] means!
x.__setitem__(x.__lt__(2), 0) # this is what x[x < 2] = 0 means!
Run Code Online (Sandbox Code Playgroud)
因为:
x < value 相当于 x.__lt__(value)x[value] 是(大致)相当于 x.__getitem__(value) x[value] = othervalue是(也粗略地)相当于x.__setitem__(value, othervalue).这可以定制,以做任何你想做的事情.就像一个例子(模仿一点numpys-boolean索引):
class Test:
def __init__(self, value):
self.value = value
def __lt__(self, other):
# You could do anything in here. For example create a new list indicating if that
# element is less than the other value
res = [item < other for item in self.value]
return self.__class__(res)
def __repr__(self):
return '{0} ({1})'.format(self.__class__.__name__, self.value)
def __getitem__(self, item):
# If you index with an instance of this class use "boolean-indexing"
if isinstance(item, Test):
res = self.__class__([i for i, index in zip(self.value, item) if index])
return res
# Something else was given just try to use it on the value
return self.value[item]
def __setitem__(self, item, value):
if isinstance(item, Test):
self.value = [i if not index else value for i, index in zip(self.value, item)]
else:
self.value[item] = value
Run Code Online (Sandbox Code Playgroud)
现在让我们看看如果你使用它会发生什么:
>>> a = Test([1,2,3])
>>> a
Test ([1, 2, 3])
>>> a < 2 # calls __lt__
Test ([True, False, False])
>>> a[Test([True, False, False])] # calls __getitem__
Test ([1])
>>> a[a < 2] # or short form
Test ([1])
>>> a[a < 2] = 0 # calls __setitem__
>>> a
Test ([0, 2, 3])
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一种可能性.你可以自由地实现你想要的几乎所有东西.
| 归档时间: |
|
| 查看次数: |
13679 次 |
| 最近记录: |