Un plugin flake8 qui vous aide à rédiger de meilleures compréhensions de liste/ensemble/dict.
Linter un projet Django ? Consultez mon livre Boost Your Django DX qui couvre Flake8 et de nombreux autres outils de qualité de code.
Python 3.9 à 3.13 pris en charge.
Tout d'abord, installez avec pip
:
python -m pip install flake8-comprehensions
Deuxièmement, si vous définissez le paramètre select
de Flake8, ajoutez-y le préfixe C4
. Sinon, le plugin devrait être actif par défaut.
<list/set/dict>
.Règles:
Il n'est pas nécessaire d'utiliser list
, set
ou dict
autour d'une expression génératrice, car il existe des compréhensions équivalentes pour ces types. Par exemple:
list(f(x) for x in foo)
comme [f(x) for x in foo]
set(f(x) for x in foo)
sous la forme {f(x) for x in foo}
dict((x, f(x)) for x in foo)
comme {x: f(x) for x in foo}
<set/dict>
.Règles:
Il n'est pas nécessaire d'utiliser une compréhension de liste dans un appel à set
ou dict
, car il existe des compréhensions équivalentes pour ces types. Par exemple:
set([f(x) for x in foo])
comme {f(x) for x in foo}
dict([(x, f(x)) for x in foo])
comme {x: f(x) for x in foo}
<list/tuple>
inutile - réécriture en tant que littéral <set/dict>
.<list/tuple>
inutile - réécrit en tant que littéral d'ensemble.<list/tuple>
inutile - réécrit en tant que littéral dict. Il n'est pas nécessaire d'utiliser une liste ou un tuple littéral dans un appel à set
ou dict
. Par exemple:
set([1, 2])
sous la forme {1, 2}
set((1, 2))
sous la forme {1, 2}
set([])
comme set()
dict([(1, 2)])
comme {1: 2}
dict(((1, 2),))
comme {1: 2}
dict([])
comme {}
<dict/list>
inutile - <builtin>
peut prendre un générateurCette règle a été abandonnée dans la version 3.4.0, car elle favorisait une augmentation de la paresse pouvant conduire à des bugs.
<dict/list/tuple>
inutile - réécriture sous forme littérale. Il est plus lent d'appeler par exemple dict()
que d'utiliser le littéral vide, car le nom dict
doit être recherché dans la portée globale au cas où il aurait été rebondi. Idem pour les deux autres types de base ici. Par exemple:
dict()
comme {}
dict(a=1, b=2)
comme {"a": 1, "b": 2}
list()
comme []
tuple()
comme ()
<list/tuple>
inutile transmis à <list/tuple>
() - <advice>
.Règles:
<list/tuple>
inutile passé à tuple() - <advice>
.<advice>
. Où <advice>
est soit :
<list/tuple>
()<list/tuple>
Il n'est pas nécessaire d'utiliser un littéral list ou tuple dans un appel à list
ou tuple
, car il existe une syntaxe littérale pour ces types. Par exemple:
tuple([1, 2])
comme (1, 2)
tuple((1, 2))
en tant que (1, 2)
tuple([])
comme ()
list([1, 2])
[1, 2]
list((1, 2))
comme [1, 2]
list([])
en tant que []
Il n'est pas nécessaire d'utiliser une list
autour d'une compréhension de liste, car elle est équivalente sans elle. Par exemple:
list([f(x) for x in foo])
comme [f(x) for x in foo]
<dict/list/set>
inutile - 'in' peut prendre un générateur.Cette règle a été abandonnée dans la version 3.4.0, car elle favorisait une augmentation de la paresse pouvant conduire à des bugs.
<list/reversed>
inutile autour de sorted(). Il n'est pas nécessaire d'utiliser list()
autour sorted()
car il renvoie déjà une liste. Il est également inutile d'utiliser reversed()
autour sorted()
car cette dernière a un argument reverse
. Par exemple:
list(sorted([2, 3, 1]))
comme sorted([2, 3, 1])
reversed(sorted([2, 3, 1]))
comme sorted([2, 3, 1], reverse=True)
reversed(sorted([2, 3, 1], reverse=True))
comme sorted([2, 3, 1])
<list/reversed/set/sorted/tuple>
inutile dans <list/set/sorted/tuple>
(). Il n'est pas nécessaire de doubler ou de double-traiter les itérables en encapsulant les fonctions répertoriées dans list
/ set
/ sorted
/ tuple
. Par exemple:
list(list(iterable))
en tant que list(iterable)
list(tuple(iterable))
en tant que list(iterable)
tuple(list(iterable))
en tant que tuple(iterable)
tuple(tuple(iterable))
en tant que tuple(iterable)
set(set(iterable))
comme set(iterable)
set(list(iterable))
comme set(iterable)
set(tuple(iterable))
en tant que set(iterable)
set(sorted(iterable))
comme set(iterable)
set(reversed(iterable))
comme set(iterable)
sorted(list(iterable))
comme sorted(iterable)
sorted(tuple(iterable))
comme sorted(iterable)
sorted(sorted(iterable))
comme sorted(iterable)
sorted(reversed(iterable))
comme sorted(iterable)
<reversed/set/sorted>
().Il n'est pas nécessaire d'inverser l'ordre d'un itérable lorsque le passer dans l'une des fonctions répertoriées modifiera à nouveau l'ordre. Par exemple:
set(iterable[::-1])
comme set(iterable)
sorted(iterable)[::-1]
comme sorted(iterable, reverse=True)
reversed(iterable[::-1])
comme iterable
<dict/list/set>
inutile - réécriture en utilisant <dict/list/set>
(). Il n'est pas nécessaire d'utiliser une compréhension dict/list/set pour construire une structure de données si les éléments sont inchangés. Enveloppez l'itérable avec dict()
, list()
ou set()
à la place. Par exemple:
{a: b for a, b in iterable}
sous la forme dict(iterable)
[x for x in iterable]
sous forme list(iterable)
{x for x in iterable}
comme set(iterable)
map
- réécriture à l'aide d'un générateur d'expression/compréhension <list/set/dict>
. map(func, iterable)
a d'excellentes performances lorsque func
est une fonction intégrée, et cela a du sens si votre fonction a déjà un nom. Mais si votre fonction est un lambda
, il est plus rapide d'utiliser une expression génératrice ou une compréhension, car cela évite la surcharge de l'appel de fonction. Par exemple:
map(lambda x: x + 1, iterable)
en (x + 1 for x in iterable)
map(lambda item: get_id(item), items)
en (get_id(item) for item in items)
list(map(lambda num: num * 2, nums))
en [num * 2 for num in nums]
set(map(lambda num: num % 2 == 0, nums))
en {num % 2 == 0 for num in nums}
dict(map(lambda v: (v, v ** 2), values))
en {v : v ** 2 for v in values}
<dict/dict comprehension>
inutile passé à dict() - supprime l'appel externe à dict() Il n'est pas nécessaire d'utiliser un dict
autour d'un dict littéral ou d'une compréhension de dict, puisque l'une ou l'autre syntaxe construit déjà un dict. Par exemple:
dict({})
comme {}
dict({"a": 1})
comme {"a": 1}
<any/all>
() empêche les courts-circuits - réécriture en tant que générateur. L'utilisation d'une compréhension de liste dans un appel à any()
/ all()
évite les courts-circuits lorsqu'une valeur True
/ False
est trouvée. La liste entière sera construite avant d'appeler any()
/ all()
, ce qui pourrait gaspiller work.part-way. Réécrivez pour utiliser une expression génératrice, qui peut s'arrêter à mi-chemin. Par exemple:
all([condition(x) for x in iterable])
sous la forme all(condition(x) for x in iterable)
any([condition(x) for x in iterable])
comme any(condition(x) for x in iterable)
Il n'est pas nécessaire d'utiliser une compréhension de dict pour construire un dict avec toutes les valeurs définies sur la même constante. Utilisez plutôt dict.fromkeys()
, ce qui est plus rapide. Par exemple:
{x: 1 for x in iterable}
sous la forme dict.fromkeys(iterable, 1)
{x: None for x in iterable}
sous la forme dict.fromkeys(iterable)