7
votes

Liste compréhension et len ​​() vs simple pour la boucle

Je suis censé prendre une liste de mots et compter tous les mots de 2 caractères ou plus de long et où le premier et le dernier caractère sont égaux.

J'ai proposé deux solutions possibles: xxx

vs. xxx

lequel serait la solution préférée? Ou y a-t-il encore mieux?


4 commentaires

Je prendrais # 2: mais est bien formaté sur plusieurs lignes. Juste parce que vous peut écrire une ligne ne signifie pas que vous devriez (même avec des générateurs ou de la Comp, etc.)


S'il vous plaît, s'il vous plaît, s'il vous plaît mesurer. Veuillez utiliser TIMINIT pour mesurer ceci. S'il vous plaît mesurer et poster les résultats.


@ S.Lott: Il n'a rien dit sur la performance. La façon préférée de faire quelque chose n'implique pas le le plus rapide moyen de faire quelque chose.


Si la question ne préfère pas les performances, qu'est-ce que cela préfère? Utilisation de la mémoire? Si c'est juste style, la question est simplement subjective et donc pauvre. "Préféré" pourrait signifier quoi que ce soit. La mesure est facile et peut être faite en premier. Si ce n'est pas mesurable, alors il est subjectif.


5 Réponses :


1
votes

Les deux sont plutôt bons.

Il y a de petites différences:

La compréhension de la liste renvoie une autre liste que vous passez à len . La première solution évite la création d'une autre liste.


0 commentaires

16
votes

Dans votre deuxième exemple, un Expression génératrice serait mieux que la liste comp si votre liste est grande.

sum(1 for word in words if len(word) >= 2 and word[0] == word[-1])


2 commentaires

TypeError: objet de type 'Generator' n'a pas de len ()


Merci! Je vais presque le suggérer.



4
votes

Le premier serait certainement la solution préférée en Python.

N'oubliez pas votre zen de Python:

le zen de Python, par Tim Peters

belle est meilleure que laide.

Explicit est meilleur que implicite.

simple est meilleur que complexe.

complexe est meilleur que compliqué.

L'appartement est mieux que d'imbriquée.

Sparse est meilleur que dense.

compte de lisibilité.

Les cas spéciaux ne sont pas assez spéciaux pour Enfreindre les règles.

Bien que la praticité bat la pureté.

Les erreurs ne doivent jamais passer en silence.

sauf si explicitement réduit le silence.

face à l'ambiguïté, refuse le tentation de deviner.

Il devrait y avoir un-- et de préférence un seul moyen envahit de le faire.

Bien que cette façon peut ne pas être évidente Au début, sauf si vous êtes néerlandais.

est maintenant meilleur que jamais.

Bien que jamais ne soit souvent meilleur que droite maintenant.

si la mise en œuvre est difficile à Expliquez, c'est une mauvaise idée.

si la mise en œuvre est facile à Expliquez, c'est peut-être une bonne idée.

Les espaces de noms sont une bonne idée de klaxonnière - Faisons plus de ceux-ci!

Autre que vos solutions sont bonnes.


2 commentaires

La formule habituelle de Zen-of-Python-Perrotting: Faites une réclamation et pointez à une ligne de la sorte comme justification, comme si c'était un texte religieux. (Je trouve la deuxième version très claire; le premier ressemble à quelque chose de porté de C.)


Je suis complètement en désaccord. Les compréhensions de la liste sont très pythoniques et lisibles.



2
votes

Je trouve personnellement la boucle explicite plus lisible, mais c'est une question beaucoup de goût (certains préfèrent le code plus court généralement, surtout quand ils doivent l'écrire).

La version peut être encore raccourcie / améliorée: P >

len(1 for word in words if len(word) >= 2 and word[0] == word[-1])


1 commentaires

A + = int (bool) est unidiomatic au point où j'allais appeler ça mal. Ne fais pas ça; L'état d'origine est beaucoup plus clair.



1
votes

Certaines autres variantes que vous voudrez peut-être envisager:

Tout d'abord, vous pouvez casser l'état du filtre dans une fonction. Cette condition est bien de toute façon, mais si elle devient plus complexe, je ferais certainement cela: xxx

suivant, si elle générer une liste (comme dans la compréhension de la liste d'origine) est acceptable, alors vous pouvez faire ceci: xxx

Il y a iTertools.Ifilter, mais si vous utilisez que vous devez utiliser à nouveau l'expression Somme à nouveau, Donc, cela ne finit pas d'autre chose plus claire.

La somme la somme montre si souvent que je suis surpris qu'il n'y ait pas un appel de bibliothèque standard pour compter le nombre d'articles Dans un itérateur (s'il y a, je ne l'ai pas trouvé). Alternativement, il serait logique si len consomme et compterait le nombre d'entrées dans un itérateur s'il n'a pas de __ len __ , mais ce n'est pas le cas.


0 commentaires