6
votes

Manière élégante de sauter des éléments dans un iérêteur

J'ai un grand iérêteur, en fait, un grand appareil donné par: xxx pré>

Je voudrais accéder au millionième élément. J'ai déjà un problème résolu de différentes manières. P>

  1. Casting iTABLE à lister et à obtenir 1000000ème élément: p>

    return islice(permutations(range(10)), 999999, 1000000).next()
    
  2. Passer manuellement des éléments jusqu'à 999999: P>

    p = permutations(range(10))
    for i, element in enumerate(p):
        if i == 999999:
            return element
    
  3. Passer manuellement Éléments V2: P>

    p = permutations(range(10))
    for i in xrange(999999): p.next()
    return p.next()
    
  4. Utilisation d'Islice de Itertools: P>

    return list(permutations(range(10)))[999999]
    


0 commentaires

3 Réponses :


16
votes

Utilisez le iTertools recette consommer à ignorer n éléments: xxx

notez le islice () appelez-les; Il utilise n, n , effectivement ne pas renvoyer rien et la suivant () La fonction tombe à la valeur par défaut.

Simplified à votre exemple, où vous souhaitez sauter 999999 éléments, puis renvoyer l'élément 1000000: xxx

islice () traite l'itérateur en C, quelque chose que les boucles python ne peuvent pas battre.

Pour illustrer, voici les horaires de seulement 10 répétitions de chaque méthode: xxx

islice ( ) La méthode est presque 7 fois plus rapide que la prochaine méthode la plus rapide.


1 commentaires

C'était rapide et vraiment détaillé une bonne réponse. À propos, vous m'avez également appris un moyen d'appeler des fonctions en utilisant le temps imparti. Merci = d



4
votes

Trouver la nième permutation peut simplement être un exemple, mais si c'est en fait le problème que vous essayez de résoudre puis il y a un meilleur moyen de le faire. Au lieu de sauter les éléments du démonteur, vous pouvez calculer directement la nième permutation. Emprunter le code de une autre réponse ici : xxx

exemple et comparaison de chronométrage: xxx

même réponse, plus de 3000 fois plus rapidement. Notez que j'ai fait une légère modification au code d'origine afin qu'elle ne détruisait plus la liste d'origine.


1 commentaires

Ce n'était pas la casquette de la question, je n'étais que curieux à la manière plus rapide de sauter des éléments d'une irable. Cependant, votre réponse est un intérêt d'intérêt de résoudre le Nth factorial encore plus rapidement. Je vous ai donné +1. THX!



2
votes

Il est effectivement gaspillé de progresser avec un million d'articles pour arriver à la suivante. Malheureusement, s'il peut être évité dépend de votre itérateur: si l'itérateur a un moyen de passer directement à un décalage particulier, il peut implémenter la méthode __ getItem __ et vous pouvez l'utiliser pour demander itérateur [1000000] directement. (Comment cela s'y rend compte jusqu'à l'algorithme de génération).

Si votre source de données doit générer toutes les valeurs antérieures afin d'y arriver, comment vous les jeter est le moindre de vos problèmes. Vous pouvez choisir une belle façon, mais c'est juste glaçage sur le gâteau.

ps. Compte tenu du contexte de votre question, j'allais définir un algorithme pour générer directement la nième permutation, mais je vois @ f.j. me battre à ça. Belle solution! : -)


2 commentaires

De nombreux processus ne peuvent pas vous donner cette option; prises de réseau par exemple. Ou un fichier avec des lignes de longueur variable, il faut passer les lignes x . Mais oui, si vous pouvez «rechercher» directement à l'article dont vous avez besoin, utilisez-le.


Exactement, c'est ce que j'essayais d'en avoir. Ce qui est "inélégant" (lu: inefficace) est qu'il n'ya souvent aucun moyen de sortir de générer les objets sautés.