flake8-comprehensions
A flake8 plugin that helps you write better list/set/dict comprehensions.
Requirements
Python 3.6 to 3.9 supported.
Installation
First, install with pip:
python -m pip install flake8-comprehensions
Second, check that flake8 lists the plugin in its version line:
$ flake8 --version
3.7.8 (flake8-comprehensions: 3.0.0, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.8.0 on Linux
Third, add the C4 prefix to your select list. For example, if you have your configuration in setup.cfg:
[flake8]
select = E,F,W,C4
Linting a Django project? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.
Rules
C400-402: Unnecessary generator - rewrite as a <list/set/dict> comprehension.
It's unnecessary to use list, set, or dict around a generator expression, since there are equivalent comprehensions for these types. For example:
- Rewrite 
list(f(x) for x in foo)as[f(x) for x in foo] - Rewrite 
set(f(x) for x in foo)as{f(x) for x in foo} - Rewrite 
dict((x, f(x)) for x in foo)as{x: f(x) for x in foo} 
C403-404: Unnecessary list comprehension - rewrite as a <set/dict> comprehension.
It's unnecessary to use a list comprehension inside a call to set or dict, since there are equivalent comprehensions for these types. For example:
- Rewrite 
set([f(x) for x in foo])as{f(x) for x in foo} - Rewrite 
dict([(x, f(x)) for x in foo])as{x: f(x) for x in foo} 
C405-406: Unnecessary <list/tuple> literal - rewrite as a <set/dict> literal.
It's unnecessary to use a list or tuple literal within a call to set or dict. For example:
- Rewrite 
set([1, 2])as{1, 2} - Rewrite 
set((1, 2))as{1, 2} - Rewrite 
set([])asset() - Rewrite 
dict([(1, 2)])as{1: 2} - Rewrite 
dict(((1, 2),))as{1: 2} - Rewrite 
dict([])as{} 
C407: Unnecessary <dict/list> comprehension - <builtin> can take a generator
It's unnecessary to pass a list comprehension to some builtins that can take generators instead. For example:
- Rewrite 
sum([x ** 2 for x in range(10)])assum(x ** 2 for x in range(10)) - Rewrite 
all([foo.bar for foo in foos])asall(foo.bar for foo in foos) - Rewrite 
filter(lambda x: x % 2 == 0, [x ** 3 for x in range(10)])asfilter(lambda x: x % 2 == 0, (x ** 3 for x in range(10))) 
The list of builtins that are checked for are:
allanyenumeratefilterfrozensetmapmaxminsortedsumtuple
C408: Unnecessary <dict/list/tuple> call - rewrite as a literal.
It's slower to call e.g. dict() than using the empty literal, because the name dict must be looked up in the global scope in case it has been rebound. Same for the other two basic types here. For example:
- Rewrite 
dict()as{} - Rewrite 
dict(a=1, b=2)as{"a": 1, "b": 2} - Rewrite 
list()as[] - Rewrite 
tuple()as() 
C409-410: Unnecessary <list/tuple> passed to <list/tuple>() - (remove the outer call to <list/tuple>``()/rewrite as a ``<list/tuple> literal).
It's unnecessary to use a list or tuple literal within a call to list or tuple, since there is literal syntax for these types. For example:
- Rewrite 
tuple([1, 2])as(1, 2) - Rewrite 
tuple((1, 2))as(1, 2) - Rewrite 
tuple([])as() - Rewrite 
list([1, 2])as[1, 2] - Rewrite 
list((1, 2))as[1, 2] - Rewrite 
list([])as[] 
C411: Unnecessary list call - remove the outer call to list().
It's unnecessary to use a list around a list comprehension, since it is equivalent without it. For example:
- Rewrite 
list([f(x) for x in foo])as[f(x) for x in foo] 
C412: Unnecessary <dict/list/set> comprehension - 'in' can take a generator.
It's unnecessary to pass a dict/list/set comprehension to 'in', as it can take a generator instead. For example:
- Rewrite 
y in [f(x) for x in foo]asy in (f(x) for x in foo) - Rewrite 
y in {x ** 2 for x in foo}asy in (x ** 2 for x in foo) 
C413: Unnecessary <list/reversed> call around sorted().
It's unnecessary to use list() around sorted() as it already returns a list. It is also unnecessary to use reversed() around sorted() as the latter has a reverse argument. For example:
- Rewrite 
list(sorted([2, 3, 1]))assorted([2, 3, 1]) - Rewrite 
reversed(sorted([2, 3, 1]))assorted([2, 3, 1], reverse=True) - Rewrite 
reversed(sorted([2, 3, 1], reverse=True))assorted([2, 3, 1]) 
C414: Unnecessary <list/reversed/set/sorted/tuple> call within <list/set/sorted/tuple>().
It's unnecessary to double-cast or double-process iterables by wrapping the listed functions within list/set/sorted/tuple. For example:
- Rewrite 
list(list(iterable))aslist(iterable) - Rewrite 
list(tuple(iterable))aslist(iterable) - Rewrite 
tuple(list(iterable))astuple(iterable) - Rewrite 
tuple(tuple(iterable))astuple(iterable) - Rewrite 
set(set(iterable))asset(iterable) - Rewrite 
set(list(iterable))asset(iterable) - Rewrite 
set(tuple(iterable))asset(iterable) - Rewrite 
set(sorted(iterable))asset(iterable) - Rewrite 
set(reversed(iterable))asset(iterable) - Rewrite 
sorted(list(iterable))assorted(iterable) - Rewrite 
sorted(tuple(iterable))assorted(iterable) - Rewrite 
sorted(sorted(iterable))assorted(iterable) - Rewrite 
sorted(reversed(iterable))assorted(iterable) 
C415: Unnecessary subscript reversal of iterable within <reversed/set/sorted>().
It's unnecessary to reverse the order of an iterable when passing it into one of the listed functions will change the order again. For example:
- Rewrite 
set(iterable[::-1])asset(iterable) - Rewrite 
sorted(iterable[::-1])assorted(iterable, reverse=True) - Rewrite 
reversed(iterable[::-1])asiterable 
C416: Unnecessary <list/set> comprehension - rewrite using <list/set>().
It's unnecessary to use a list comprehension if the elements are unchanged. The iterable should be wrapped in list() or set() instead. For example:
- Rewrite 
[x for x in iterable]aslist(iterable) - Rewrite 
{x for x in iterable}asset(iterable)