Quelle est la meilleure structure de données pour le stockage d'un ensemble de quatre (ou plus) des valeurs?
Dire que j'ai la suite variables
et de ses correspondants values
qui représente un record
.
name = 'abc'
age = 23
weight = 60
height = 174
Veuillez noter que le value
peuvent être de différents types
(string
, integer
, float
, de référence-à-tout-autre-objet, etc).
Il y aura beaucoup de records
(au moins >100 000 habitants). Chaque record
sera unique
lorsque l'ensemble de ces quatre variables
(en fait son values
) sont mis ensemble. En d'autres termes, il n'existe pas de record
avec tous les 4 values
sont les mêmes.
Je suis en train d'essayer de trouver une structure de données efficace dans Python
qui me permettra de stocker et d') récupérer records
fondée sur l'un quelconque de ces variables
dans log(n)
temps de la complexité.
Par exemple:
def retrieve(name=None,age=None,weight=None,height=None)
if name is not None and age is None and weight is None and height is None:
/* get all records with the given name */
if name is None and age is not None and weight is None and height is None:
/* get all records with the given age */
....
return records
La façon dont le retrieve
devrait être appelé est comme suit:
retrieve(name='abc')
Ci-dessus doit retourner [{name:'abc', age:23, wight:50, height=175}, {name:'abc', age:28, wight:55, height=170}, etc]
retrieve(age=23)
Ci-dessus doit retourner [{name:'abc', age:23, wight:50, height=175}, {name:'def', age:23, wight:65, height=180}, etc]
Et, j'ai peut-être besoin d'ajouter un ou deux de plus variables
à cet enregistrement dans le futur. Par exemple, disons, sex = 'm'
. Ainsi, la retrieve
fonction doit être évolutive.
Donc en bref: Est-il une structure de données dans Python
qui permettra storing a record
avec n
nombre de columns
(nom, âge, sexe, poids, taille, etc) et retrieving records
basé sur (un) de l' column
dans logarithmic
(ou, idéalement, constant - O(1)
look-up de temps) de la complexité?
- Pourriez-vous veuillez justifier l'-1? C'est une véritable question de programmation.
- Peut-être cela vous aidera - wiki.python.org/moin/TimeComplexity ?
- Pourquoi pas à l'aide de sql pour cela? Semble plus approprié. Python a la prise en charge intégrée pour sqlite.
- SQL sera lent, OP mentionne de temps en complexité, il n'est probablement pas très heureux d'être lié par les I/O.
- Cette question est au sujet de fournir une mise en œuvre d'une telle structure de données, ou est-il quant à savoir si ou non un prêt-à-utiliser de l'exécution?
- aussi regarder pandas.DataFrame
- J'ai besoin d'essayer et d'éviter tout db opérations ici qui peut ralentir les choses..
- Je suis à la recherche d'un construire-dans le type de données qui peuvent fournir cette. Si aucune accumulation dans la structure de données est disponible, alors j'ai besoin d'utiliser la combinaison de l'existant, des types de données intégrés à venir avec un définis par l'utilisateur structure de données qui a regarder le temps < log(n) le temps de la complexité.
- Merci pour le partage du temps de la complexité de la page. Bonne référence. Merci!
- vous êtes les bienvenus, je ne connaissais pas avant, afin de sera certainement venir dans maniable pour moi aussi! 🙂
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas une seule structure de données construite en Python qui fait tout ce que vous voulez, mais il est assez facile d'utiliser une combinaison de ceux-la, il ne avoir à atteindre vos objectifs et de le faire assez rapidement.
Par exemple, disons que votre contribution a été les données suivantes dans un csv fichier appelé
employees.csv
avec des noms de champ définis comme indiqué par la première ligne:Voici de travail code qui montre comment lire et stocker ces données dans une liste d'enregistrements, et de créer automatiquement de séparer les tables de recherche pour rechercher des enregistrements associés avec les valeurs contenues dans les champs de chacun de ces enregistrements.
Les enregistrements sont des instances d'une classe créée par
namedtuple
qui est une mémoire très efficace, car chaque on manque d'une__dict__
attribut que des instances de classe contiennent normalement. En les utilisant, il sera possible d'accéder aux champs de chaque nom en utilisant la syntaxe à point, commerecord.fieldname
.Le look-up tables sont
defaultdict(list)
instances, qui fournissent un dictionnaire comme O(1) coup d'oeil de temps en moyenne, et également autoriser plusieurs valeurs associées à chacun. Donc, la clé est la valeur de la valeur du champ recherchées, et les données qui y sont associées seront une liste de l'entier des indices de laPerson
registres informatisés, conservés dans lesemployees
liste avec que donc ils vont tous être relativement faible.Noter que le code de la classe est entièrement piloté par les données, en ce qu'elle ne contient pas tout codé en dur noms de champs qui sont prises à partir de la première ligne de données au format csv, fichier d'entrée lorsqu'il est lu. Bien sûr, lors de l'utilisation d'une instance, tous les
retrieve()
les appels de méthode doit fournir les noms de champs valides.Mise à jour
Modifié pour ne pas créer une table pour chaque valeur unique de chaque champ lorsque le fichier de données est d'abord lu. Maintenant, le
retrieve()
méthode "paresseusement" crée seulement lorsqu'il est nécessaire (et sauve/met le résultat en cache pour une utilisation future). Également modifié pour fonctionner dans Python 2.7+ 3 inclus.x.De sortie:
Non, il n'y a aucun. Mais vous pouvez essayer de le mettre en œuvre sur la base d'un dictionnaire par la valeur de la dimension. Aussi longtemps que vos valeurs sont hashable de cours. Si vous implémentez une classe personnalisée pour vos dossiers, chaque dictionnaire contiendra des références sur les mêmes objets. Cela vous fera économiser de la mémoire.
Donné http://wiki.python.org/moin/TimeComplexity comment à ce sujet:
AGE
,NAME
, etc.AGE
,NAME
) possible des valeurs de la colonne (35 ou "m").VALUES = [ [35, "m"], ...]
AGE
,NAME
) être des listes d'indices à partir de laVALUES
liste.VALUES
de sorte que vous savez que la première colonne est l'âge et le deuxième, c'est le sexe (vous pouvez éviter cela et utiliser les dictionnaires, mais ils présentent une grande mémoire footrpint et avec plus de 100K objets cela peut ou ne pas être un problème).Puis le
retrieve
fonction pourrait ressembler à ceci:Alors, c'est ce que vous obtenez
Si vous voulez un dictionnaire, vous pouvez effectuer les opérations suivantes:
mais encore une fois, les dictionnaires sont un peu lourd sur le côté de la mémoire, donc si vous pouvez aller avec des listes de valeurs, il pourrait être mieux.
À la fois dictionnaire et la liste de récupération sont en O(1) en moyenne - pire des cas pour le dictionnaire est O(n) - ce qui devrait être assez rapide. Le maintien qui sera un peu de douleur, mais pas tellement. Pour "écrire", vous avez juste à ajouter à la
VALUES
liste, puis ajouter l'index dansVALUES
à chacun des dictionnaires.De cours, alors le mieux serait de tester les performances de votre mise en œuvre effective et à chercher d'éventuelles améliorations, mais j'espère que cela a du sens, et vous va 🙂
EDIT:
Veuillez noter que, comme @moooeeeep dit, cela ne fonctionnera que si vos valeurs sont hashable et, par conséquent, peuvent être utilisés comme clés de dictionnaire.
Vous pouvait atteindre des temps logarithmique de la complexité dans une base de données relationnelle à l'aide des index (
O(log(n)**k)
avec une seule colonne d'index). Puis de récupérer les données juste à construire SQL approprié:Exemple:
De sortie:
set()
objet). Il est disponible sur Python 2.7 et Python 3.