Mr Squidr
Mr Squidr

Reputation: 143

More efficient way to replace zeros to ones and ones to zeros in a string (e.g. "100001" to "011110")

At the moment I'm doing it like this but the problem is I'm looping through thousands of such strings (which are all much longer than the example string given below) and current method takes a very long time to complete:

    example_string = '1001011101010010101010100100000001111011010101'
    reversed = ''
    for c in example_string:
        if c == '1':
            reversed += '0'
        elif c == '0':
            reversed += '1'
    print(reversed)

Upvotes: 1

Views: 2458

Answers (4)

Martin Nečas
Martin Nečas

Reputation: 593

example_string.translate(str.maketrans("01","10"))

Upvotes: 7

Gábor Fekete
Gábor Fekete

Reputation: 1358

Using bitwise operators:

s = '1001011101010010101010100100000001111011010101'

i = int(s,2)
i=((1<<i.bit_length())-1)^i
t=bin(i)[2:].zfill(len(s))
print(s)
print(t)

Output:

1001011101010010101010100100000001111011010101
0110100010101101010101011011111110000100101010

Explanation:

First I convert the string to an integer (s -> i).
Then I make a number that has the same length as i in binary but has all ones.
This is achieved by bitshifting 1 to the left n times where n is the length of the binary string, it's safer to use the .bit_length() method of the integer though. This bitshifted integer is still the power of two so we have to subtract 1 to get all ones. Then using the xor (exclusive or) operator the result will be the opposite of the input's. After this it's just changing back to binary string, removing the 0b part from the start and filling with zeroes to the left to match the length of the original string.

Upvotes: 1

Tom
Tom

Reputation: 765

If speed is really important

You can use bit manipulation:

example_string = '1001011101010010101010100100000001111011010101'
reverted = ''

i = int(example_string, 2)

reverted = bin((i ^ (2 ** (i.bit_length()+1) - 1)))[-len(example_string):]

print(reverted)


# reverted : 0110100010101101010101011011111110000100101010

Upvotes: 1

Gal
Gal

Reputation: 504

using strings to store binary numbers is not a very good option, but when using string it is better to use a list instead of a string to store the result of the reversing. every time you do reserved += '0' reserved is copied into memory, which takes a long time, but with lists it is not as slow. try this:

reversed = []
for c in example_string:
    if c == '1':
        reversed.append('0')
    elif c == '0':
        reversed.append('1')
print(''.join(reversed))

Upvotes: 1

Related Questions