Python - 在字符串中翻转二进制1和0

Jus*_*ent 7 python

我试图采取以字符串形式的二进制数和翻转的1和0,也就是在字符串中改变所有的1的为0的,和所有的0年代到1的.我是Python的新手,现在已经花了好几个小时试图解决它.

Amb*_*ber 27

>>> ''.join('1' if x == '0' else '0' for x in '1000110')
'0111001'
Run Code Online (Sandbox Code Playgroud)

a for b in c模式是一个生成器表达式,它根据不同的系列生成一系列项目.在这种情况下,原始系列是字符(因为您可以在Python中迭代字符串,它为您提供构成该字符串的字符),而新系列是一组字符,其中0和1翻转.

'1' if x == '0' else '0'非常简单 - 它给了我们任何一个10不是x.我们为x原始字符集中的每个字符执行此操作,然后将join()它们全部放在一起(''在每个项目之间使用空字符串,也就是没有任何内容),从而为我们提供最终字符串,该字符串是原始字符的所有相反字符,结合.

  • 为了使它太聪明一半,你可以选择用`'01'[x =='0']`替换`if`表达式.我仍然更喜欢你的答案,但我想我会提到它. (2认同)

wkl*_*wkl 12

另一种方法是使用string.translate()string.maketrans()

from string import maketrans
bitString = "10101010100011010"
flippedString = bitString.translate(maketrans("10","01"))
Run Code Online (Sandbox Code Playgroud)


小智 8

您已经标记了对此的答案,但我还没有看到我喜欢的方法。我在这里假设您有一个已知长度的二进制数 - 在我给出的示例中为 8 位。

如果您可以从数字开始,则可以执行以下操作:

myNumber = 0b10010011
myNumberInverted = myNumber ^ 0b11111111
Run Code Online (Sandbox Code Playgroud)

^运算符执行按位异或。

如果确实必须从字符串开始,可以先转换为整数,然后再执行此操作。

myString = '10010011'
myNumber = int(myString, 2)
myNumberInverted = myNumber ^ 0b11111111
Run Code Online (Sandbox Code Playgroud)


Xor*_*lev 6

Amber 的回答虽然优秀,但可能不是最清楚的,所以这是一个超级基本的迭代示例:

b_string = "1100101"
ib_string = ""

for bit in b_string:
  if bit == "1":
    ib_string += "0"
  else:
    ib_string += "1"

print ib_string
Run Code Online (Sandbox Code Playgroud)

这可以通过更好的方式来完成......替换,理解,但这是一个例子。

一旦你理解了这个问题的基础,我就会从这个问题的其他答案中学习。这种方法缓慢而痛苦。为了获得最佳性能,正如穆罕默德·阿尔卡鲁里( Muhammad Alkarouri)指出的那样,string.translate/maketrans组合是要走的路。紧随其后的是领悟。我的代码是最慢的。

  • 我想避免鼓励人们对字符串使用 `+=`,而不是 `join()` - 不仅 `join()` 更 Pythonic,而且它也是更有效的一般用法方法。早点灌输是个好习惯。 (4认同)
  • 一般来说,不要推测时间。在这种情况下,`timeit ''.join('1' if x == '0' else '0' for x in b_string)` 在我的机器上给出 5.3 微秒,而 `timeit b_string.translate(maketrans("10" , "01"))` 给出 979 _nanoseconds_。 (2认同)

Wil*_*ill 6

如果速度很重要:

并且您已经有了表示二进制字符串的十进制整数,那么位操作会稍微快一些。

bin((i ^ (2 ** (i.bit_length()+1) - 1)))[3:]
Run Code Online (Sandbox Code Playgroud)

如果你只得到二进制字符串,那么使用str.replace@Amy 给出的方法:

s.replace('1', '2').replace('0', '1').replace('2', '0')
Run Code Online (Sandbox Code Playgroud)

我使用以下要点测试了此处提出的各种方法和位操作方法:

检测结果

i = 129831201;
s = '111101111010001000100100001';
Run Code Online (Sandbox Code Playgroud)

位操作给定十进制int

bin((i ^ (2 ** (i.bit_length()+1) - 1)))[3:]

1000000 loops, best of 3: 0.647 usec per loop
Run Code Online (Sandbox Code Playgroud)

给定二进制字符串的位操作:

bin((int(s, 2) ^ (2**(len(s)+1) - 1)))[3:]

1000000 loops, best of 3: 0.922 usec per loop
Run Code Online (Sandbox Code Playgroud)

顺序str.replace

s.replace('1', '2').replace('0', '1').replace('2', '0')

1000000 loops, best of 3: 0.619 usec per loop
Run Code Online (Sandbox Code Playgroud)

str.maketrans

s.translate(str.maketrans('10', '01'))

1000000 loops, best of 3: 1.16 usec per loop
Run Code Online (Sandbox Code Playgroud)

''.join 使用字典映射:

flip = {'1':'0', '0':'1'}; ''.join(flip[b] for b in s)

100000 loops, best of 3: 2.78 usec per loop
Run Code Online (Sandbox Code Playgroud)

''.join 有条件的:

''.join('1' if b == '0' else '0' for b in s)

100000 loops, best of 3: 2.82 usec per loop
Run Code Online (Sandbox Code Playgroud)