波浪符在Python中有什么用途?

我能想到的一件事是在字符串或列表的两侧做一些事情,比如检查字符串是否为回文:

def is_palindromic(s):
    return all(s[i] == s[~i] for i in range(len(s) / 2)) 

还有其他好的用法吗?


当前回答

这是次要的用法是波浪…

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio)) 
    return data.loc[~in_test_set], data.loc[in_test_set]

上面的代码来自“Hands On Machine Learning”

您可以使用波浪号(~符号)作为-符号索引标记的替代

就像你用- - is表示整数索引一样

ex)

array = [1,2,3,4,5,6]
print(array[-1])

是一样的吗

打印(数组(~ 1))

其他回答

我唯一一次在实践中使用它是在numpy/pandas中。例如,使用.isin() dataframe方法。

在文档中,他们给出了这个基本的例子

>>> df.isin([0, 2])
        num_legs  num_wings
falcon      True       True
dog        False       True

但是如果你想要所有不在[0,2]中的行呢?

>>> ~df.isin([0, 2])
        num_legs  num_wings
falcon     False       False
dog        True        False

应该注意,在数组索引的情况下,array[~i]等于reversed_array[i]。它可以被视为从数组末尾开始的索引:

[0, 1, 2, 3, 4, 5, 6, 7, 8]
    ^                 ^
    i                ~i

解释为什么-x -1在一般情况下是正确的(对于整数)

有时(例如),人们对~运算符的数学行为感到惊讶。例如,他们可能会推断~18的结果应该是13,而不是求19(因为bin(18)给出了'0b10010',反转位将得到'0b01101',这表示13 -对吧?)或者他们可能期望237(将输入视为带符号的8位数),或者其他对应于较大整数大小的正数值(例如机器字大小)。

注意,在这里,位11101101的有符号解释(被视为无符号,给出237)是…-19年。对于更大数量的比特,也会发生同样的情况。事实上,只要我们使用至少6位,并将结果视为有符号,我们就会得到相同的答案:-19。

数学规则——先求负再减1——适用于所有输入,只要我们使用足够的比特,并将结果视为有符号。

And, this being Python, conceptually numbers use an arbitrary number of bits. The implementation will allocate more space automatically, according to what is necessary to represent the number. (For example, if the value would "fit" in one machine word, then only one is used; the data type abstracts the process of sign-extending the number out to infinity.) It also does not have any separate unsigned-integer type; integers simply are signed in Python. (After all, since we aren't in control of the amount of memory used anyway, what's the point in denying access to negative values?)

这打破了许多来自C环境的人的直觉,在C环境中,只使用unsigned类型进行位操作,然后再应用2s-补解释(并且仅在适当的情况下;如果一个值被视为一组“标志”,那么有符号的解释就不太可能有意义)。然而,Python对~的实现与其其他设计选择是一致的。

如何强迫无符号行为

如果我们想要从18位的逆运算中得到13 237或其他类似的结果,我们需要一些外部机制来指定要逆的位数。(同样,18在概念上有任意多个前导0在它的二进制表示中以任意位数表示;颠倒它们会得到前导为1的东西;而在2s补中解释它会得到负的结果。)

最简单的方法是简单地屏蔽那些任意多的比特。为了从18的倒数得到13,我们需要5位,所以我们用0b11111进行掩码,即31。更一般地说(并为原始行为提供相同的接口):

def invert(value, bits=None):
    result = ~value
    return result if bits is None else (result & ((1 << bits) - 1))

另一种方法,根据Andrew Jenkins在链接示例问题中的回答,是直接用蒙版进行异或。有趣的是,我们可以使用XOR来处理默认的、任意精度的情况。我们简单地使用一个任意大小的掩码,即一个概念上具有任意数量的二进制表示的1位的整数,即-1。因此:

def invert(value, bits=None):
    return value ^ (-1 if bits is None else ((1 << bits) - 1))

然而,像这样使用XOR会得到一个奇怪的负值结果——因为所有那些任意的-许多设置位“之前”(在更重要的位置)XOR掩码没有被清除:

>>> invert(-19, 5) # notice the result is equal to 18 - 32
-14

除了作为位补操作符外,~还可以帮助恢复布尔值,尽管它不是常规的bool类型,而应该使用numpy.bool_。


这在,

import numpy as np
assert ~np.True_ == np.False_

反转逻辑值有时很有用,例如,下面的~操作符用于清理数据集,并返回没有NaN的列。

from numpy import NaN
import pandas as pd

matrix = pd.DataFrame([1,2,3,4,NaN], columns=['Number'], dtype='float64')
# Remove NaN in column 'Number'
matrix['Number'][~matrix['Number'].isnull()]

它叫做二进制一号的补体(~)

它返回一个数的二进制数的补数。它翻转比特。2的二进制是00000010。它的补数是11111101。

这是-3的二进制。结果是-3。类似地,~1的结果是-2。

~-3

输出:2

同样,-3的补是2。