简体   繁体   English

(〜)为什么我的位没有翻转?

[英](~) Why are my bits not flipping?

I thought that ~ should make 1s into 0s and vice-versa. 我认为〜应该将1s变为0,反之亦然。 I used it in my code, yet I'm getting -2s and -1s. 我在我的代码中使用它,但我得到-2s和-1s。

def inverse_graph(graph):
    # for each vertex in graph
    revg = list(graph)
    for i, line in enumerate(revg):
        for j, vertex in enumerate(line):
            if  i != j:
                # flip value
                graph[i][j] = ~ graph[i][j]
                #if vertex == 0:
                #    graph[i][j] = 1;
                #else:
                #    graph[i][j] = 0;
    return revg



def test():
        g1 = [[0, 1, 1, 0],
              [1, 0, 0, 1],
              [1, 0, 0, 1],
              [0, 1, 1, 0]]
        assert inverse_graph(g1) == [[0, 0, 0, 1],
                                     [0, 0, 1, 0],
                                     [0, 1, 0, 0],
                                     [1, 0, 0, 0]]
        g2 = [[0, 1, 1, 1],
              [1, 0, 1, 1],
              [1, 1, 0, 1],
              [1, 1, 1, 0]]
        assert inverse_graph(g2) == [[0, 0, 0, 0],
                                     [0, 0, 0, 0],
                                     [0, 0, 0, 0],
                                     [0, 0, 0, 0]]

............................................................................................................................................................................................................. .................................................. .................................................. .................................................. .................................................. .....

Actually, -2 is ~1. 实际上,-2 〜1。 Two's complement , remember? 两个补充 ,还记得吗?

>>> bin(1)
'0b1'
>>> bin(~1)
'-0b10'

The thing is: you're not using bits, but integers. 问题是:你不是使用比特,而是使用整数。 So either you want to revert to using eg Booleans (which read less nicely) or you want to use some expression like 0 if x else 1 to flip your elements. 所以要么你想要恢复使用例如布尔(看起来不那么好),要么你想使用像0 if x else 1表达式, 0 if x else 1来翻转你的元素。

Tip: you can use comprehensions to write this more elegantly: 提示:您可以使用理解来更优雅地编写:

>>> flipped = lambda graph: [ [0 if x else 1  for x in row]  for row in graph]
>>> flipped( [ [1, 0], [0, 1] ] )
[[0, 1], [1, 0]]

With numpy it is much easier. 随着numpy它更容易。

>>> import numpy as np
>>> g1=np.array([[0, 1, 1, 0],
...              [1, 0, 0, 1],
...              [1, 0, 0, 1],
...              [0, 1, 1, 0]])
>>> g2=1-g1
>>> g2
array([[1, 0, 0, 1],
       [0, 1, 1, 0],
       [0, 1, 1, 0],
       [1, 0, 0, 1]])

~ will work with Boolean datatype: 〜将使用布尔数据类型:

>>> g1=np.array([[0, 1, 1, 0],   # 1 represents True and 0 represents False
...              [1, 0, 0, 1],
...              [1, 0, 0, 1],
...              [0, 1, 1, 0]], dtype=bool)
>>> ~g1
array([[ True, False, False,  True],
       [False,  True,  True, False],
       [False,  True,  True, False],
       [ True, False, False,  True]], dtype=bool)

If you want complement(~) in 0s and 1s rather than in True False, this will do the trick: 如果你想在0和1而不是在真假的complement(~) ,这将做的伎俩:

>>> ~g1+0
array([[1, 0, 0, 1],
       [0, 1, 1, 0],
       [0, 1, 1, 0],
       [1, 0, 0, 1]])

As xtofl has pointed out, Python's integers use Two's complement representation. 正如xtofl所指出的,Python的整数使用二进制补码表示。 This means that the bitwise inverse of 0 is not 1 , but an infinitely long sequence of binary 1 s, which is interpreted as -1 . 这意味着0的按位反转不是1 ,而是无限长的二进制1 s序列,它被解释为-1 The inverse of 1 is not 0 , but an infinite number of ones, followed by one zero (which is -2 ). 1的倒数不是0 ,而是无穷多的1,后跟一个零(即-2 )。

Of course, the number of bits stored for each integer is not infinite. 当然,为每个整数存储的位数不是无限的。 Python will normally use the C integer type long that your system defines (it is usually 32 or maybe 64 bits long), but operations that would overflow will instead automatically switch to Python's own arbitrary precision long type if the value is too large to fit (this conversion is handled transparently within the int type in Python 3). Python中,通常会使用C整数类型long ,你的系统定义(通常是32或可能64位长),但操作会溢出反而会自动切换到Python的任意精度的long型如果值太大,不适合(这种转换在Python 3中的int类型中透明地处理。

Anyway, an alternative solution is to use: 无论如何,另一种解决方案是使用:

graph[i][j] = 1 - graph[i][j]

Or, if you don't mind the values becoming instances of the int subtype bool : 或者,如果您不介意值成为int子类型bool实例:

graph[i][j] = not graph[i][j]

Python's bool values are still usable as numbers ( False works just like 0 and True is just like 1 ). Python的bool值仍可用作数字( False就像0一样, True就像1 )。 The only real difference is that they'll print out with text instead of digits. 唯一真正的区别是它们会用文字而不是数字打印出来。

While the others are right, an easier way of saying 0 if x else 1 is not x or maybe int(not x) . 虽然其他的是正确的,但0 if x else 1 not x或者可能是int(not x) ,则更容易说0 if x else 1

not x returns False if x != 0 and True otherwise. 如果x != 0 not x返回False ,否则返回True False and True are bool s, which is a subclass of int . FalseTruebool ,它是int的子类。 They can readily be used in a calculation, but for the case you prefer to get proper 0 s and 1 s, or if you need them for indexing a dict , int(not x) might be better. 它们可以很容易地用于计算,但是对于你喜欢获得正确的0秒和1秒的情况,或者如果你需要它们来索引dictint(not x)可能会更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM