Python 中的波浪号运算符

2024-12-16 08:35:00
admin
原创
151
摘要:问题描述:Python 中波浪符号运算符有什么用途?我能想到的一件事是在字符串或列表的两边做一些事情,比如检查字符串是否是回文:def is_palindromic(s): return all(s[i] == s[~i] for i in range(len(s) / 2)) 还有什么好用途吗?解...

问题描述:

Python 中波浪符号运算符有什么用途?

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

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

还有什么好用途吗?


解决方案 1:

它是一个一元运算符(采用单个参数),借用自 C,其中所有数据类型都只是解释字节的不同方式。它是“反转”或“补充”运算,其中输入数据的所有位都被反转。

在 Python 中,对于整数,整数的二进制补码表示的位会被反转(就像b <- b XOR 1每个单独的位一样),并且结果会再次解释为二进制补码整数。因此对于整数,~x相当于(-x) - 1

运算符的具体化形式~operator.invert。若要在您自己的类中支持此运算符,请为其提供一个__invert__(self)方法。

>>> import operator
>>> class Foo:
...   def __invert__(self):
...     print 'invert'
...
>>> x = Foo()
>>> operator.invert(x)
invert
>>> ~x
invert

任何类中,如果实例的“补集”或“逆集”也是同一类的实例,则该类都可能适合使用反转运算符。但是,如果误用运算符重载,则会导致混淆,因此在__invert__向您的类提供方法之前,请确保这样做确实有意义。(请注意,字节字符串 [例如:'xff'] 不支持此运算符,即使反转字节字符串的所有位是有意义的。)

解决方案 2:

~是Python 中的按位补码运算符,本质上是计算-x - 1

因此表格看起来就像

i  ~i
-----
0  -1
1  -2
2  -3
3  -4 
4  -5 
5  -6

因此,对于,i = 0它会s[0]s[len(s) - 1],对于i = 1s[1]与进行比较s[len(s) - 2]

至于您的其他问题,这对于一系列按位黑客攻击非常有用。

解决方案 3:

需要注意的是,在数组索引的情况下,array[~i]相当于reversed_array[i]。它可以看作是从数组末尾开始索引:

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

解决方案 4:

除了作为按位补码运算符之外,~还可以帮助恢复布尔值,尽管它不是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()]

解决方案 5:

我在实践中使用过的唯一一次方法是numpy/pandas。例如,使用.isin() 数据框方法。

在文档中他们展示了这个基本示例

>>> 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

解决方案 6:

解释为什么-x -1通常是正确的(对于整数)

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

请注意,此处位的有符号11101101解释(如果视为无符号,则为237)是... -19。对于较大的位数,情况也是如此。事实上,只要我们使用至少 6 位,并将结果视为有符号,我们就会得到相同的答案:-19。

数学规则 - 取反,然后减一 - 适用于所有输入 - 只要我们使用足够多的位并将结果视为有符号的。

在 Python 中,从概念上讲,数字使用任意数量的位。实现将根据表示数字所需的内容自动分配更多空间。(例如,如果值“适合”一个机器字,则只使用一个;数据类型抽象了将数字符号扩展为无穷大的过程。)它也没有任何单独的无符号整数类型;整数在 Python 中只是有符号的。(毕竟,既然我们无论如何都无法控制使用的内存量,那么拒绝访问负值有什么意义呢?)

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

如何强制未签名的行为

如果我们想通过反转 的位来获得13237其他类似的东西18,我们需要一些外部机制来指定要反转的位数。(同样,18概念上, 在其二进制表示中以任意数量的位具有任意多个前导 0;反转它们将得到具有前导 1 的结果;而将其解释为二进制补码将得到负结果。)

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

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

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

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

但是,像这样使用 XOR 会产生奇怪的负结果value- 因为 XOR 掩码“之前”(在更重要的位置)的所有任意设置位都没有被清除:

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

解决方案 7:

我正在解决这道leetcode 问题,偶然发现了名叫Zitao Wang 的用户提供的这个漂亮的解决方案。

问题如下:对于给定数组中的每个元素,找到所有剩余数字的乘积,而不使用除法,并且O(n)及时

标准解决方案是:

Pass 1: For all elements compute product of all the elements to the left of it
Pass 2: For all elements compute product of all the elements to the right of it
        and then multiplying them for the final answer 

他的解决方案只使用了一个 for 循环。他使用~

def productExceptSelf(self, nums):
    res = [1]*len(nums)
    lprod = 1
    rprod = 1
    for i in range(len(nums)):
        res[i] *= lprod
        lprod *= nums[i]
        res[~i] *= rprod
        rprod *= nums[~i]
    return res

解决方案 8:

我发现波浪号运算符的一个用途是将某个底数的分数转换为十进制的分数。

例如,假设您要将 0.01 从 5 进制转换为 10 进制。执行此操作的公式应如下所示:

(0 5^0) + (0 5^-1) + (1 * 5^-2)

我们不需要计算整数部分,但如果我们需要的话,代码看起来可能是这样的:

integer = sum(digit * (5 ** exp) for exp, digit enumerate(reversed(str(integer)))

我们首先反转整数,因为最小的指数位于整数部分的末尾,即计算如下 (x 5^n) + (x 5^n-1) + (x * 5^n-2) ...

对于小数,最大的指数是小数部分的开始。所以我们不需要反转整数。但是如果我们enumerate再次尝试使用该方法,它只会生成从 0 开始的正数。

我们可以做的是for exp, digit in enumerate(str(fraction)),我们可以digit乘以5 ** -exp。我们需要从中减去一,-exp这样 0 就变成 -1,1 就变成 -2,依此类推,所以我们可以写成digit * (5 ** -(exp+1))。我们可以-(exp+1)简单地用替换~i,代码如下:

fraction = sum(digit * (5 ** ~i) for exp, digit in enumerate(str(fraction))

当基数中的符号不​​是数字时,这种方法特别有用,例如,以 5 为基数的系统使用 a、b、c、d 和 e 分别表示 0、1、2、3 和 4。

解决方案 9:

它被称为二进制补码(〜)

它返回数字二进制的补码。它翻转位。2 的二进制为 00000010。它的补码为 11111101。

这是 -3 的二进制表示。因此,结果为 -3。类似地,~1 的结果为 -2。

~-3

输出 :2

再次,-3 的补数是 2。

解决方案 10:

这是次要用法,是波浪号......

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”

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

就像使用减号 - 用于整数索引一样

前任)

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

print(array[~1])

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1314  
  随着数字化时代的飞速发展,企业数据成为了核心资产,其安全性至关重要。信创国产电脑作为保障数据安全的关键一环,正逐渐在企业中得到广泛应用。信创国产电脑基于自主研发的技术体系,从硬件到软件都致力于构建安全可靠的环境,为企业数据安全保驾护航。接下来,我们将深入探讨信创国产电脑如何在多个层面提升企业数据安全性。硬件层面的安全保...
什么是信创概念   16  
  随着信息技术的飞速发展,电脑作为重要的办公和生产工具,其性能对于用户的工作效率和体验有着至关重要的影响。在当前信创产业蓬勃发展的背景下,国产电脑逐渐崛起,与进口品牌电脑形成了激烈的竞争态势。了解信创国产电脑与进口品牌在性能方面的差异,对于企业和个人在选择电脑设备时具有重要的指导意义。处理器性能对比处理器是电脑的核心组件...
国产化信创什么意思   16  
  信创国产化适配方案在当前数字化时代具有极其重要的意义。随着全球政治经济形势的变化以及信息技术的飞速发展,实现信息技术的自主可控成为国家和企业的关键需求。信创国产化适配方案旨在将各类信息技术产品和服务进行国产化替代,降低对国外技术的依赖,保障信息安全,推动国内信息技术产业的发展。这不仅关乎国家的信息安全战略,也为国内相关...
信创电脑   17  
  信创国产化操作系统的兴起,是我国信息技术产业发展历程中的一个重要里程碑。随着全球科技竞争的日益激烈,实现信息技术的自主可控成为国家战略的关键部分。国产化操作系统作为信创产业的核心基础,其发展不仅关乎操作系统本身的技术突破,更对整个软件生态产生了深远影响。从底层架构的变革到应用开发模式的转变,从软件企业的发展策略调整到用...
信创国产软件有哪些   13  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用