[PYTHON] Comment se débarrasser des longues inclusions

Les longues inclusions sont difficiles

En Python, les collections sont généralement générées en inclusion (je pense).

Cependant, quand cela devient un peu compliqué, la notation d'inclusion est difficile à lire.

#Inclure de force la liste Fizz Buzz
fb = ["Fizz Buzz" if i % 15 == 0 
      else "Fizz" if i % 3 == 0 
      else "Buzz" if i % 5 == 0 
      else i 
      for i in range(30)]

Dans ce cas, il est plus facile de lire en écrivant une instruction for.

Cependant, le style d'écriture consistant à effectuer de petits changements tout en exposant l'objet avant l'initialisation est quelque peu coupable (lorsque la préférence fonctionnelle est forte).

fb = []
for i in range(30):
    if i % 15 == 0:
        fb.append("Fizz Buzz")
    elif i % 3 == 0:
        fb.append("Fizz")
    elif i % 5 == 0:
        fb.append("Buzz")
    else:
        fb.append(i)

Que faire?

Générateur + collecteur

Il est possible de définir un générateur avec rendement et de créer une collection basée sur celui-ci.

def _fb():
    for i in range(30):
        if i % 15 == 0:
            yield "Fizz Buzz"
        elif i % 3 == 0:
            yield "Fizz"
        elif i % 5 == 0:
            yield "Buzz"
        else:
            yield i

fb = list(_fb)

Plus concis

↑ n'est pas mal, mais après avoir défini le générateur, la procédure pour l'assigner à une variable via la fonction de liste est compliquée.

De plus, si vous oubliez d'en faire une liste et de recevoir l'itérateur directement sous forme de variable, cela peut être un foyer de bogues.

Je veux que la définition utilisant yield soit interprétée comme la définition de la liste telle quelle.

Ceci peut être réalisé en utilisant un décorateur.

def comprehension(collector):
    def ret(func):
        return collector(func())
    return ret

#La liste est affectée à la variable "fb" en exécutant ce qui suit.
@comprehension(list)
def fb():
    for i in range(30):
        if i % 15 == 0:
            yield "Fizz Buzz"
        elif i % 3 == 0:
            yield "Fizz"
        elif i % 5 == 0:
            yield "Buzz"
        else:
            yield i

Ancienne histoire

Le premier matériel source est le décorateur appelé collection dans la bibliothèque appelée funcy. Transformez la fonction de générateur en une fonction qui renvoie une liste. Avec cela, Fizz Buzz peut être écrit comme suit:

from funcy import collecting

@collecting
def _fb():
    for i in range(30):
        if i % 15 == 0:
            yield "Fizz Buzz"
        elif i % 3 == 0:
            yield "Fizz"
        elif i % 5 == 0:
            yield "Buzz"
        else:
            yield i

fb = _fb()

Cependant, il est difficile de définir la fonction une fois.

Raquette [pour / list](https://docs.racket-lang.org/reference/for.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for%2Flist% J'ai pensé que si je pouvais écrire quelque chose comme 29% 29), j'ai trouvé une solution qui ne renvoie pas de fonction dans le décorateur.

Recommended Posts

Comment se débarrasser des longues inclusions
Comment se débarrasser des pictogrammes personnalisés du serveur dans message.content
Comment obtenir des éléments de type dictionnaire de Python 2.7
Débarrassez-vous de KeyError de python
réussir à se débarrasser des pylônes lourds dans vim-lsp
[Linux] [C / C ++] Résumé de la façon d'obtenir pid, ppid, tid
Comment obtenir une liste d'exceptions intégrées pour python
Comment obtenir un aperçu de vos données dans Pandas
Comment obtenir une liste de liens à partir d'une page de wikipedia
Débarrassez-vous de slow scp -pr
Résumé de l'utilisation de pandas.DataFrame.loc
Résumé de l'utilisation de pyenv-virtualenv
Comment obtenir la version Python
Comment démarrer avec Scrapy
Comment démarrer avec Python
Comment démarrer avec Django
Résumé de l'utilisation de csvkit
Comment obtenir l'ID de Type2Tag NXP NTAG213 avec nfcpy
[Python] Comment obtenir la fraction d'un nombre naturel à grande vitesse
[Python] Comment obtenir le premier et le dernier jour du mois
J'ai essayé de résumer brièvement la procédure de démarrage du développement de Django
Comment enregistrer une partie d'une longue vidéo en utilisant OpenCV
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Technique Python pour ceux qui veulent se débarrasser des débutants
Comment éliminer le "Les balises doivent être un tableau de hachages." Erreur dans l'API qiita
[Python] Résumé de l'utilisation des pandas
Comment accélérer la belle instanciation de soupe
Comment obtenir l'identifiant du parent avec sqlalchemy
Comment vérifier la version de Django
Comment obtenir une adresse IP lorsque Tornado + nginx
Comment installer CatBoost [à partir de janvier 2020]
Comment calculer Utiliser% de la commande df
Comment obtenir stacktrace en python
[Python2.7] Résumé de l'utilisation d'unittest
Comment obtenir une sortie colorée sur la console
Jupyter Notebook Principes d'utilisation
Bases de PyTorch (1) -Comment utiliser Tensor-
Résumé de l'utilisation de la liste Python
[Python2.7] Résumé de l'utilisation du sous-processus
Résumé de l'écriture d'AWS Lambda
Débarrassez-vous des images DICOM en Python
[Question] Comment utiliser plot_surface de python
Comment calculer la volatilité d'une marque
Comment utiliser Folium (visualisation des informations de localisation)
Comment trouver la zone du diagramme de Boronoi
[Python] Comment utiliser deux types de type ()
Résumé de la façon d'importer des fichiers dans Python 3
Comment obtenir les résultats de l'identifiant dans Celery
[NNabla] Comment obtenir la sortie (variable) de la couche intermédiaire du réseau construit
[Django] Comment obtenir des données en spécifiant SQL.
Comment obtenir de l'aide dans un shell interactif
Pas beaucoup de mention de la façon d'utiliser Pickle
Résumé de l'utilisation de MNIST avec Python
[Python] Débarrassez-vous de la datation avec des expressions régulières
Comment spécifier des attributs avec Mock of Python
Comment implémenter "named_scope" de RubyOnRails avec Django
Comment obtenir des données d'article à l'aide de l'API Qiita
Je veux obtenir les données de League of Legends ③
Je veux obtenir les données de League of Legends ②