Je le code suivant en Python:.
if point not in reversed(points):
6 Réponses :
def point_to_index(point): try: return points.index(point) except: points.append(point) return len(points)-1 Update: Added in Nathan's exception code.
Cela ne fait-il pas que la même chose pour le cas lorsque le point n'existe pas? Que diriez-vous de cela dans l'affaire d'exception? retour len (points) - 1 code>? Est len () o (1) en python?
@Nathan - c'est ce que j'ai fait. Voir ma réponse. Oui, Len est O (1) pour les listes.
C'est une amélioration énorme B>! Avant de courir pendant une heure et j'ai appelé cela environ 250000 fois. Maintenant, cela fonctionne depuis une demi-heure et la fonction a été appelée 350000 fois, avec seulement ce changement!
Vous souhaitez utiliser un Ensemble :
>>> x = set() >>> x set([]) >>> x.add(1) >>> x set([1]) >>> x.add(1) >>> x set([1])
Qu'en est-il de besoin d'indices constants, comme l'a dit l'OP? Aucun ordre dans les ensembles.
Si vous demandez à l'Op pourquoi il a besoin de l'index, vous trouverez probablement qu'il dépend de la mise en œuvre. Je parie qu'un ensemble est la bonne réponse, nonobstant ce que l'OP a demandé.
@hugh wat? Ce n'est pas parce qu'il a besoin de tester pour que l'adhésion ne signifie pas qu'un ensemble est automatiquement la bonne structure de données.
@Triptych Vous avez raison en ce que ce n'est pas automatiquement la bonne réponse, mais l'OP a dit dans un commentaire qu'il fabrique "[au moins] 350 000" appelle à l'adhésion, ce qui correspond à ce que des ensembles et des dictionnaires excellent à. Nous ne pouvons vraiment pas savoir quelle est la réponse optimale pour le problème réel de l'OP, cependant, sans plus d'informations sur les raisons pour lesquelles, exactement, les listes et leurs indices sont essentiels, donc dans son problème limité, des solutions ici fonctionneront. Comme Hughdbrown, je soupçonne plus d'informations, une solution impliquant des ensembles fonctionnerait mieux, mais pour le moment, sa spéculation.
Cela traversera au plus une fois:
def point_to_index(point): for index, this_point in enumerate(reversed(points)): if point == this_point: return len(points) - (index+1) else: points.append(point) return len(points)-1
C'est une bonne idée, sauf que je rencontre des problèmes de mémoire, je ne veux donc pas ajouter une autre copie. Un dict code> a-t-il un concept d'ordre?
Oui, à la fois append () et len () sont O (1) pour les listes.
Et non, pas de concept d'ordre dans dict code> s
Sauf si vous utilisez un ordre ordonné.
@Évan j'ai considéré que, mais un dict ordonné conserverait bien sûr une copie ordonnée des points, ce qui semble en l'espèce d'engager un coût de mémoire inacceptable.
Votre suggestion d'utilisation inverse () est bonne, mais elle présente également l'inconvénération de l'inversion des indeces également. Cependant, maintenant que j'y pense, s'il y a un moyen de préparer un élément au début d'une liste au lieu de l'ajouter à la fin, je pourrais retourner len (points) - points.index (point) < / code>
Bien sûr, vous avez raison d'inverser les indices. J'ai changé mon code en conséquence. La préparation est une mauvaise idée - c'est une opération O (n) versus O (1) pour l'annexe.
Je dois mentionner de nombreux programmeurs respectés en tenant compte de l'utilisation de la manipulation d'exception pour un flux logique d'une pratique médiocre médiocre. La manipulation des exceptions doit être réservée à la manipulation des conditions anormales, non normales. Je comprends que cela donne le comportement souhaité ici, mais essayez de ne pas en faire une habitude.
@gotgenes - list.index appelle une erreur, donc je le traite comme un. Je suppose que les concepteurs de langue souhaitaient empêcher les personnes de tester la vérité du résultat de liste.index et ont choisi d'utiliser une exception dans ce cas
@Triptych @gotgenes Je dois être d'accord avec TripTych. Si List.index est renvoyé, dites, -1 ou aucun ou faux quand il échoué, il n'y aurait pas besoin d'essayer, sauf.
Comme les autres ont dit, envisagez d'utiliser SET ou DICT. Vous n'expliquez pas pourquoi vous avez besoin des indices. S'ils sont nécessaires seulement pour attribuer des identifiants uniques aux points (et je ne peux pas facilement trouver une autre raison de les utiliser), la dict fonctionnera effectivement beaucoup mieux, par exemple
points = {} def point_to_index(point): if point in points: return points[point] else: points[point] = len(points) return len(points) - 1
Y a-t-il un moyen pour moi d'obtenir la liste des points triés par index?
Si vous êtes inquiet pour l'utilisation de la mémoire, mais souhaitez optimiser l'affaire commune, gardez un dictionnaire avec les derniers points n et leurs index. Points_dict = Dictionnaire, max_cache = taille du cache.
def point_to_index(point): try: return points_dict.get(point, points.index(point)) except: if len(points) >= max_cache: del points_dict[points[len(points)-max_cache]] points.append(point) points_dict[points] = len(points)-1 return len(points)-1
C'est essentiellement un dict ordonné, comme Tonfa suggère ci-dessous: Stackoverflow.com/questions/1319254/ ...
Bon dieu! C'est tellement plus rapide que d'utiliser seulement une liste!
Ce que vous voulez vraiment, c'est un dict ordonné (insertion clé détermine la commande): p>
Y a-t-il une raison pour laquelle vous utilisez une liste et non un ensemble?
Pourquoi avez-vous besoin de l'index du point de la liste? Si vous pouviez ajouter tous vos éléments à une fois dans un ensemble, vous pouvez exécuter ce code en 5-10 secondes, à une supposition.