9
votes

Python, liste paresseuse

est-il possible d'avoir une liste être évaluée paresseusement en python?

par exemple xxx

si la liste a été réglée pour évaluer la paressologie, la ligne finale serait [2]


2 commentaires

Ce n'est pas ce que j'ai compris une évaluation paresseuse. Je dirais que cela ressemble plus à ceci: nous voulons trouver les 30 premiers nombres positifs dont le carré est divisible par 3. Avec une langue désireuse, vous codez soit pour effectuer des performances - tandis que (Longueur <30) si (i * i% 3 == 0) Liste + = i ++; ou expressivité (mais jetant d'énormes listes inutiles en cours de route) - list1 = plage 0..10000; pour i dans la liste1 si je * i% 3 == 0 list2.add i; list2.trim (30) . Avec paresseux, vous écrivez quelque chose de plus comme celui-ci, mais obtenez la performance du premier. Daniel Tao l'explique brillamment .


Une manière paresseuse pourrait ressembler à ceci: Plage (). Filtre (var). Var * Var% 3 == 0) .take (30) - Il est écrit très expressément, mais le code n'est pas écrit impérativement. Il est exécuté: gamme génère 1. filtre - échoue car 1 * 1% 3! = 0 . Puis plage génère 2. filtre échoue. Puis plage génère 3. filtre passe parce que 3 * 3% 3 == 0 . Prenez File d'attente comme une réponse. Après prendre a pris 30, l'algorithme s'arrête. Il utilise uniquement autant de mémoire que cela doit, mais il est également très lisible (et parallèle).


4 Réponses :



11
votes

Le concept d'évaluation "paresseux" est normalement livré avec des langues fonctionnelles - mais dans ceux que vous ne pouviez pas réaffecter deux valeurs différentes sur le même identifiant, il n'ya donc pas que votre exemple n'est pas reproduit.

Le point n'est pas À propos de la paresse du tout - c'est que l'utilisation d'un identifiant est garantie pour être identique à une référence à la même valeur que l'identifiant se réfère et réaffectant un identifiant, un nom nu , à une valeur différente, on garantit que l'identifiant se réfère à une valeur différente de celle-ci. La référence à la première valeur (objet) n'est pas perdue.

Considérez un exemple similaire où la ré-affectation à un nom nu n'est pas en jeu, mais plutôt tout autre type de mutation (pour un objet mutable, Bien sûr - les chiffres et les chaînes sont immuables), y compris une affectation à quelque chose sinon qu'un nom nu: xxx

car il n'y a pas de a - ... qui réaffie le nom nu a , mais plutôt un a [:] = ... qui réaffie a 'S Contenu , il est trivialement facile de faire de Python comme vous le souhaitez (et cela prendrait des efforts pour le rendre "impatient"! -) ... si la paresse vs empressement eu quelque chose à voir avec l'un de ces cas (ce qu'il ne le fait pas; -).

Soyez juste conscient de la sémantique parfaitement simple de «attribuer à un nom nu» (vs attribution à rien d'autre, lequel Peut être modifié de manière variée et contrôlée en utilisant vos propres types de manière appropriée) et l'illusion optique de "paresseux vs désireux" pourrait espérer Y Vanish; -)


0 commentaires

11
votes

est tombé sur ce post lorsque vous recherchez une véritable implémentation de la liste paresseuse, mais cela ressemblait à une chose amusante pour essayer de travailler.

La mise en œuvre suivante fait fondamentalement ce qui a été demandé à l'origine: p>

>>> a = 1
>>> l = LazyClosureSequence(lambda: [a])
>>> print l
[1]
>>> a = 2
>>> print l
[2]


1 commentaires

Toujours intéressant. Merci