Un complemento flake8 que le ayuda a escribir mejores comprensiones de listas, conjuntos y dictados.
¿Linting un proyecto Django? Consulte mi libro Boost Your Django DX que cubre Flake8 y muchas otras herramientas de calidad de código.
Compatible con Python 3.9 a 3.13.
Primero, instale con pip
:
python -m pip install flake8-comprehensions
En segundo lugar, si define la configuración select
de Flake8, agréguele el prefijo C4
. De lo contrario, el complemento debería estar activo de forma predeterminada.
<list/set/dict>
.Normas:
No es necesario utilizar list
, set
o dict
alrededor de una expresión generadora, ya que existen comprensiones equivalentes para estos tipos. Por ejemplo:
list(f(x) for x in foo)
como [f(x) for x in foo]
set(f(x) for x in foo)
como {f(x) for x in foo}
dict((x, f(x)) for x in foo)
como {x: f(x) for x in foo}
<set/dict>
.Normas:
No es necesario utilizar una lista por comprensión dentro de una llamada a set
o dict
, ya que existen comprensiones equivalentes para estos tipos. Por ejemplo:
set([f(x) for x in foo])
como {f(x) for x in foo}
dict([(x, f(x)) for x in foo])
como {x: f(x) for x in foo}
<list/tuple>
innecesario: reescribir como un literal <set/dict>
.<list/tuple>
innecesario: reescribir como un literal establecido.<list/tuple>
innecesario: reescribir como un literal dict. No es necesario utilizar una lista o un literal de tupla dentro de una llamada a set
o dict
. Por ejemplo:
set([1, 2])
como {1, 2}
set((1, 2))
como {1, 2}
set([])
como set()
dict([(1, 2)])
como {1: 2}
dict(((1, 2),))
como {1: 2}
dict([])
como {}
<dict/list>
: <builtin>
puede llevar un generadorEsta regla se eliminó en la versión 3.4.0 porque promovía un aumento en la pereza que podría generar errores.
<dict/list/tuple>
innecesaria: reescribir como literal. Es más lento llamar, por ejemplo dict()
que usar el literal vacío, porque el nombre dict
debe buscarse en el ámbito global en caso de que haya sido rebote. Lo mismo ocurre con los otros dos tipos básicos aquí. Por ejemplo:
dict()
como {}
dict(a=1, b=2)
como {"a": 1, "b": 2}
list()
como []
tuple()
como ()
<list/tuple>
innecesario pasado a <list/tuple>
() - <advice>
.Normas:
<list/tuple>
innecesaria pasada a tuple() - <advice>
.<advice>
. Donde <advice>
es:
<list/tuple>
()<list/tuple>
No es necesario utilizar un literal de lista o tupla dentro de una llamada a list
o tuple
, ya que existe una sintaxis literal para estos tipos. Por ejemplo:
tuple([1, 2])
como (1, 2)
tuple((1, 2))
como (1, 2)
tuple([])
como ()
list([1, 2])
como [1, 2]
list((1, 2))
como [1, 2]
list([])
como []
No es necesario utilizar una list
alrededor de una lista por comprensión, ya que es equivalente sin ella. Por ejemplo:
list([f(x) for x in foo])
como [f(x) for x in foo]
<dict/list/set>
: 'in' puede requerir un generador.Esta regla se eliminó en la versión 3.4.0 porque promovía un aumento en la pereza que podría generar errores.
<list/reversed>
innecesaria alrededor de sorted(). No es necesario utilizar list()
alrededor de sorted()
ya que ya devuelve una lista. Tampoco es necesario utilizar reversed()
alrededor de sorted()
ya que este último tiene un argumento reverse
. Por ejemplo:
list(sorted([2, 3, 1]))
como sorted([2, 3, 1])
reversed(sorted([2, 3, 1]))
como sorted([2, 3, 1], reverse=True)
reversed(sorted([2, 3, 1], reverse=True))
como sorted([2, 3, 1])
<list/reversed/set/sorted/tuple>
dentro de <list/set/sorted/tuple>
(). No es necesario realizar doble conversión o doble proceso de iterables envolviendo las funciones enumeradas dentro de list
/ set
/ sorted
/ tuple
. Por ejemplo:
list(list(iterable))
como list(iterable)
list(tuple(iterable))
como list(iterable)
tuple(list(iterable))
como tuple(iterable)
tuple(tuple(iterable))
como tuple(iterable)
set(set(iterable))
como set(iterable)
set(list(iterable))
como set(iterable)
set(tuple(iterable))
como set(iterable)
set(sorted(iterable))
como set(iterable)
set(reversed(iterable))
como set(iterable)
sorted(list(iterable))
como sorted(iterable)
sorted(tuple(iterable))
como sorted(iterable)
sorted(sorted(iterable))
como sorted(iterable)
sorted(reversed(iterable))
como sorted(iterable)
<reversed/set/sorted>
().No es necesario invertir el orden de un iterable cuando pasarlo a una de las funciones enumeradas cambiará el orden nuevamente. Por ejemplo:
set(iterable[::-1])
como set(iterable)
sorted(iterable)[::-1]
como sorted(iterable, reverse=True)
reversed(iterable[::-1])
como iterable
<dict/list/set>
- reescribir usando <dict/list/set>
(). No es necesario utilizar una comprensión dict/list/set para construir una estructura de datos si los elementos no se modifican. Envuelva el iterable con dict()
, list()
o set()
en su lugar. Por ejemplo:
{a: b for a, b in iterable}
como dict(iterable)
[x for x in iterable]
como list(iterable)
{x for x in iterable}
como set(iterable)
map
: reescribir usando una expresión generadora/comprensión <list/set/dict>
. map(func, iterable)
tiene un gran rendimiento cuando func
es una función incorporada y tiene sentido si su función ya tiene un nombre. Pero si su función es lambda
, es más rápido usar una expresión generadora o una comprensión, ya que evita la sobrecarga de llamada a la función. Por ejemplo:
map(lambda x: x + 1, iterable)
a (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))
a {v : v ** 2 for v in values}
<dict/dict comprehension>
innecesario pasado a dict() - eliminar la llamada externa a dict() No es necesario utilizar un dict
alrededor de un dict literal o de comprensión de dict, ya que cualquiera de las dos sintaxis ya construye un dict. Por ejemplo:
dict({})
como {}
dict({"a": 1})
como {"a": 1}
<any/all>
() evita cortocircuitos; reescribe como generador. El uso de una lista por comprensión dentro de una llamada a any()
/ all()
evita un cortocircuito cuando se encuentra un valor True
/ False
. La lista completa se construirá antes de llamar any()
/ all()
, lo que podría desperdiciar work.part-way. Vuelva a escribir para usar una expresión generadora, que puede detenerse en parte. Por ejemplo:
all([condition(x) for x in iterable])
como all(condition(x) for x in iterable)
any([condition(x) for x in iterable])
como any(condition(x) for x in iterable)
No es necesario utilizar una comprensión de dictado para crear un dictado con todos los valores establecidos en la misma constante. Utilice dict.fromkeys()
en su lugar, que es más rápido. Por ejemplo:
{x: 1 for x in iterable}
como dict.fromkeys(iterable, 1)
{x: None for x in iterable}
como dict.fromkeys(iterable)