J'ai besoin de stocker des objets comptant un numéro (> 2) des variables d'éléments entier et effectuez des recherches rapides à l'aide de toutes les variables de membre comme clé de recherche.
Pour une illustration plus facile, disons que les objets sont des tuples de 3 entiers et je dois faire des recherches rapides en utilisant n'importe quel élément d'un tuple comme clé dans une liste de tels tuples: p> look-ups serait comme: p > collection.lookup_by_first_element(1) # Return (1, 200, 9)
collection.lookup_by_second_element(300) # Return (2, 300, 8)
collection.lookup_by_third_element(250) # Return None
3 Réponses :
Ceci est une solution simple. Vous pouvez facilement mettre cela dans une classe et fournir une interface NATATER.
using keyed_dict: 1.09672546387e-05 using numpy_lookup: 0.000250101089478 using keyed_dict: 3.00407409668e-05 using numpy_lookup: 0.00193691253662 using keyed_dict: 0.000190019607544 using numpy_lookup: 0.0199580192566 using keyed_dict: 0.00195384025574 using numpy_lookup: 0.317503929138 using keyed_dict: 0.0319399833679 using numpy_lookup: 15.0127439499
Ah, je vois que les valeurs sont uniques. Eh bien, utilisez simplement un dict régulier au lieu d'un titre de défaut.
J'ai mis en place votre méthode dans une classe et j'ai essayé d'expliquer pourquoi o (1) Les recherches dict sont plus rapides que la recherche basée sur la matrice (c'est O (n)) dans ma réponse ci-dessous (que vous avez bien démontré par l'analyse comparative avec TIMINIT code>, mais ne pas dire pourquoi il devrait être beaucoup plus rapide).
Utilisation de NUMPY:
>>> import numpy as np >>> collection = [(1, 200, 9), ... (2, 300, 8), ... (3, 400, 7)] >>> collection = np.array(collection) >>> def f(d, c, v): ... # d: collection, c: column, v: value ... if np.any(d[:, c]==v): return d[d[:, c]==v] ... return 'None' ... >>> f(collection, 0, 1) array([[ 1, 200, 9]]) >>> f(collection, 1, 300) array([[ 2, 300, 8]]) >>> f(collection, 2, 250) 'None'
Désolé d'être une critique, mais cela est de façon plus lente que d'utiliser une dict. Voir ma réponse mise à jour.
Il y a des façons plus rapides. Voir la réponse de Senderle ci-dessous.
Envoyer a raison (j'ai suscité), mais je veux élaborer (et plus que juste dans un commentaire).
Les recherches du dictionnaire sont O (1) et vraiment vite (fondamentalement, votre clé est transformée en hachage qui s'adresse un emplacement spécifique en mémoire pour récupérer immédiatement vos données de). P>
En contraste à la recherche d'une valeur en recherchant une matrice est lente au moins O (n), donc pour les plus grands tableaux qu'il faudra plus longtemps pour trouver la bonne valeur. (Par exemple, vous devez passer à travers toutes les clés N, trouver le bon, puis retourner le tuple.) P>
Donc, si vos clés sont uniques comme vous le dites, il est logique de créer un grand Dictionnaire indexé en fonction de chaque touche que vous pouvez utiliser pour rechercher. Accordé est que vous devrez représenter chaque tuple d'articles M (m = 3 dans votre cas), M Times dans le dictionnaire, tandis que avec un seul tableau, il suffit de représenter une fois dans le tableau. P>
SO. Vous souhaitez définir une classe de collection p> le Et vos recherches fonctionnent comme vous avez demandé p> c.collection_dict code> est: p>
Y a-t-il une raison pour laquelle vous avez utilisé un dict code> au lieu de defaultDict code> comme dans la réponse de l'expéditeur? Il a utilisé Liste code> comme default_factory code> pour le defaultDict code>, la structure résultante est donc différente. Votre dict contient des touches de 2 tuple qui pointent sur des valeurs 3 tuple, où Senderle a des touches 2-Toile qui indiquent que la liste des valeurs contenant chacune une 3 tuple. Je suppose que donne des tuples sont immuables, il n'y a pas de valeur par défaut_constructeur gagné lorsque vous souhaitez des valeurs de tuple dans la dict.
@Davos - OP a réclamé chaque clé est Unique et voulait que chaque recherche renvoie une tuple pas une liste de tuples. Je suis d'accord que cela semble être une configuration étrange, mais cela pourrait avoir des cas d'utilisation. E.G., Si chaque colonne est un identifiant unique qui ne sera jamais répété (par exemple, Employee_id_number, adresse e-mail, SSN). D'accord de manière plus générale si c'est quelque chose comme (nom, naissance_date, home_town), alors vous voudriez qu'une recherche renvoie une liste de tuples correspondants.
Merci, j'ai raté ce commentaire à leur sujet d'être unique, cela l'explique. Quand ils sont uniques, l'autre réponse crée une structure dans laquelle une entrée ressemble à ce (0, 1): [(1, 200, 9)], code> de sorte que le tuple est de sorte que le tuple est en quelque sorte boxé de manière redondante. Une liste (sur 1), qui me perplexe.
Cela peut être fait avec n dictionnaires pour des valeurs uniques, dans les multi-cartes pour non unique. Mettez-les dans une classe et donnez aux noms descriptifs de l'évaluateur.
Les valeurs sont toujours uniques? Sinon, vous voulez juste le premier tuple pour l'avoir?
Pour clarifier: les valeurs sont uniques dans toutes les colonnes i>, ou juste une fois? I.e., si
(1,2,3) code> apparaît, peut-il(3,4,5) code> apparaît?@Thénatos: dans ma situation (3,4,5) ne peut pas apparaître, mais maintenant je suis aussi curieux d'une solution qui nous permettait également (3,4,5) apparaissent également.
@kaadam, une solution à base de dictionnaire est susceptible d'être plus efficace que toute solution numpy / tableau. Voir ma réponse mise à jour.