La façon dont vous l'avez écrit ci-dessus est en fait bon python idiomatiques. Si nous analysons l'algorithme, nous verrons qu'il fait essentiellement ceci:
- Faire une liste d'éléments qui satisfont le prédicat. (Croît linéairement avec n)
- Choisir un élément aléatoire dans cette liste. (Temps constant)
La seule autre façon de procéder serait de choisir un élément au hasard, de décider s'il satisfait le prédicat, et de choisir à nouveau si ce n'est pas le cas. Cet algorithme est un peu plus complexe. Dans le cas où 90% de la liste satisfait le prédicat, cela fonctionnera beaucoup plus vite que votre solution. Dans le cas où seulement 10% de la liste satisfait le prédicat, il fonctionnera beaucoup plus lentement, car il y a de fortes chances qu'il choisisse aléatoirement un élément donné et vérifie si le prédicat est satisfait sur cet élément plus d'une fois. Maintenant, vous pouvez envisager de mémoriser votre prédicat, mais vous allez toujours sélectionner beaucoup de données aléatoires. Cela se résume à ceci: à moins que votre solution ne soit particulièrement inadaptée à vos données, restez-y, parce que c'est génial. Personnellement, je réécris comme ceci:
intlist = range(1,10)
randomeven = random.choice([i for i in intlist if i % 2 == 0])
C'est un peu plus concis, mais il va courir exactement le même que votre code existant.
même le sélecteur _random_ doit savoir quoi choisir. cette ligne de code supplémentaire vous blesse? – mykhal
Je dirais que cela dépend du nombre d'éléments exclus par votre prédicat. Si elle est inférieure à 50%, alors choisir d'abord un élément de manière aléatoire et tester le prédicat par la suite pourrait être plus efficace. D'un autre côté, si seulement quelques éléments correspondent à votre prédicat, il pourrait être préférable de les filtrer auparavant. –
@Felix_Kling Même si vous excluez moins de 50% des éléments de la liste, il n'y a aucun moyen de savoir combien de temps cela prendra pour l'exécuter. –