3 votes

Opération bit à bit en Python sur de grandes chaînes binaires

Je veux effectuer une opération de type bit par bit sur des chaînes binaires d'une longueur supérieure à 100 zéros et uns. Je sais que je peux les convertir en utilisant quelque chose comme int('1'*100, 2) qui imprime 1267650600228229401496703205375L avec L à la fin. Ensuite, j'utilise les opérateurs bitwise de Python mais je pense que c'est une mauvaise idée de les convertir en entier. Existe-t-il une autre façon de procéder ?

3voto

Resonance Points 578

Je suppose que vous n'aimez pas l'idée d'utiliser des nombres entiers parce que cela obscurcit vos données sous-jacentes. De plus, il est difficile de travailler avec des chaînes de caractères qui commencent par "0" (parce qu'elles sont coupées lors de la conversion en un nombre entier), sans parler des subtilités des nombres entiers signés et de l'endiveté.

Essayez d'utiliser le module bitarray, qui peut être installé avec pip : pip install bitarray .

from bitarray import bitarray
ba1 = bitarray('0' + '1'*100)
ba2 = bitarray('1' + '0'*100)

len(ba1)  # 101
len(ba2)  # 101
ba1[0]    # False
ba2[0]    # True

ba1 | ba2  # bitarray('1111111111.......)

# get your string back
ba1.to01()  # "01111111......."

Je ne peux pas parler de l'efficacité. Mais au moins, on sait clairement avec quoi on travaille.

Fonctionne également en python3

Docs : https://pypi.python.org/pypi/bitarray/0.8.1

0voto

grochmal Points 1775

Ne pas effectuer d'opérations bit à bit sur des chaînes de caractères de type 0 et 1 qui est tout simplement mauvais et lent. Vous devez convertir les chaînes de caractères en nombres réels, car le traitement de plusieurs bits se fait alors en une seule fois. Il n'y a rien de mal à :

int('1'*128,2) & int('1'*128,2)

Mais si vous avez déjà des chaînes de 0 et 1 et vous voulez contrôler l'opération bit à bit sur certaines parties des chaînes de caractères. Vous pouvez faire ce qui suit :

l = '1'*1024
r = '1'*1024
print map(lambda x: x[0] & x[1], [(int(l[i:i+64], 2), int(r[i:i+64], 2)) for i in range(0,1024,64)])

Cela permet d'utiliser efficacement le & sur de petits morceaux (64 bits) de la chaîne, de gauche à droite.

Vous pouvez appeler bin() sur chaque résultat et les concaténer à nouveau si vous avez besoin d'une chaîne. (en prenant soin d'enlever le 0b au début de la sortie de bin() )


version de python 3 :

l = '1'*1024
r = '1'*1024
print(list(map(lambda x: x[0] & x[1], [(int(l[i:i+64], 2), int(r[i:i+64], 2)) for i in range(0,1024,64)])))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X