6
votes

Extrêmement grande liste booléenne en python

Je veux créer un objet dans Python qui est une collection d'environ 200 000 000 valeurs vraies / fausses. De sorte que je puisse changer ou rappeler le plus efficacement une valeur vraie / falsification, de sorte que je puisse déterminer rapidement si un nombre donné, comme 123 456 000 est vrai ou faux ou modifier sa valeur.

est la meilleure façon de faire cela une liste? ou un tableau? ou une classe? Ou juste un long int utilisant des opérations de bits? ou quelque chose d'autre?

Je suis un peu noob, donc vous devrez peut-être épeler des choses pour moi plus que si je posais la question dans l'une des autres langues que je connais mieux. S'il vous plaît donnez-moi des exemples de la manière dont l'utilisation de cet objet regarderait.

merci


1 commentaires

Sont les vraies / fausses valeurs denses ou clairsemées? Sont-ils uniformément distribués ou sont-ils susceptibles d'être des gammes plus denses et de pelotonnées? Le choix idéal de la structure de données diffère en fonction de ceux-ci. Bien sûr, vous n'avez peut-être pas besoin de "idéal".


6 Réponses :


3
votes

Avez-vous envisagé d'utiliser une base de données légère comme SQLite?


1 commentaires

+1. 200 millions de bits représentent environ 24 mégaoctets de données - tandis que cela pourrait facilement s'intégrer en mémoire sur une machine moderne, à tout moment, vous arrivez à cette taille de la structure en mémoire, vous devez probablement au moins déterminer si une base de données serait une meilleure solution.



12
votes

Vous pouvez essayer le bitarray module ou écrire un chose utilisant un tableau d'entiers vous-même.


1 commentaires

Merci! Je n'ai jamais installé de module avant et j'ai un peu de problème: SuperUserSer.com/Questions/56316/...



4
votes

"Déterminez rapidement si un nombre donné, tel que 123 456 000 est" dans le "vrai" défini ou "faux".

C'est ce qu'est un Set est pour .

L'ensemble "True" est un ensemble de tous les nombres.

Pour faire un drapeau booléen "true" d'un numéro, ajoutez-le au vrai jeu.

Pour faire un numéro Boolean Drapeau "False", retirez-le du vrai jeu.

La vie sera beaucoup plus simple.


5 commentaires

+1: il est simple à utiliser et peut être suffisamment efficace pour une liste de plaide


Disons que la moitié des valeurs sont vraies. La taille de l'objet INT est de 12 octets, c'est-à-dire 1,2 Go pour stocker les clés + mémoire supplémentaire pour la table de hachage réelle. En utilisant un tableau de bit, l'utilisation de la mémoire sera de 25 Mo. Je pense que c'est une différence significative.


@ Lukáš Lalinský: Votre analyse est bonne. Cependant, je ne pense pas que cela soit pertinent, sauf si votre processeur n'a pas de mémoire disponible. Sur la plupart des transformateurs modernes, il y a beaucoup de mémoire et le 25m vs. 1,2 g ne compte pas beaucoup beaucoup.


Eh bien, j'ai du mal à faire perdre 1 Go de RAM de la meilleure façon de faire quelque chose. :) Bien sûr, c'est un moyen simple et cela fonctionne bien si vous avez beaucoup moins de valeurs vraies que de fausses valeurs, mais ce n'est pas le meilleur moyen.


Étant donné que la RAM n'est pas une ressource consommable, je ne peux pas appliquer "déchets" à ce sujet - à moins que vous ne l'appuie hors du processeur et que je le jette. La mémoire est une ressource, comme le temps qui fait partie de l'équation de compromis. Mémoire - dans ce cas - peut être utilisée pour que moins de temps soit prise en essayant de gérer des bits individuels dans un tableau de bits.



1
votes

À première vue, le module Python Bitvector sonne comme il fait exactement ce que vous voulez. Il est disponible à http: //cobweb.ecn.purdue. Edu / ~ kak / dist / bitvector-1.5.1.html et puisqu'il s'agit d'un code python pur, il s'exécutera sur n'importe quelle plate-forme sans compilation nécessaire.

Vous avez mentionné que vous avez besoin de vitesse dans l'obtention et définir toute valeur true-fausse arbitraire. Pour cela, vous devez utiliser un tableau Python, plutôt qu'une liste, et si vous allez à l'URL ci-dessus et parcourez le code source pour Bitvector, vous pouvez constater qu'il repose bien sur des tableaux Python. P>

Idéalement. , vous encapsuleriez ce que vous faites dans une classe que les sous-classes de Bitvector, c'est-à-dire P>

class TFValues(BitVector):
   pass


0 commentaires

3
votes

Vous aimerez peut-être aussi essayer le module Bitstring , qui est pur python. En interne, tout est stocké sous forme de tableau d'octets et le mors masquage et de changement de bits est fait pour vous:

from bitstring import BitArray
# Initialise with two hundred million zero bits
s = BitArray(200000000)
# Set a few bits to 1
s.set(1, [76, 33, 123456000])
# And test them
if s.all([33, 76, 123456000]):
    pass


0 commentaires

0
votes

Si les bits définis sont principalement consécutifs, il existe également la possibilité de stocker une liste de gammes, par exemple. le module PYPI https://pypi.org/project/range_set/ qui est compatible API compatible avec Python définir classe.


0 commentaires