Repository: biopython/biopython

Issue:
Code refactoring to dictionary and set comprehensions
In Python 2.6, `dict` and `set` comprehensions were not supported. Since Python 2.7 they are, so code can be re-written more cleanly like:

```
>>> dict((a,b) for a,b in ((1,2),))
{1: 2}
>>> {a:b for a,b in ((1,2),)}
{1: 2}
```

Biopython includes examples of the old syntax, e.g.

```
$ grep -r -e "dict(" -e "set(" biopython/ | grep -w for | head
biopython//Bio/SeqUtils/ProtParam.py:            prot_dic = dict((k, 0) for k in IUPACData.protein_letters)
biopython//Bio/SeqUtils/__init__.py:    onecode = dict((k.upper(), v) for k, v in
biopython//Bio/SeqIO/_convert.py:    mapping = dict((chr(q + 33), str(q)) for q in range(0, 93 + 1))
biopython//Bio/SeqIO/_convert.py:    mapping = dict((chr(q + 64), str(q)) for q in range(0, 62 + 1))
biopython//Bio/SeqFeature.py:        if len(set(loc.strand for loc in self.parts)) == 1:
biopython//Bio/motifs/__init__.py:            self._pseudocounts = dict((letter, value[letter]) for letter in self.alphabet)
biopython//Bio/motifs/__init__.py:            self._background = dict((letter, value[letter]) for letter in self.alphabet)
biopython//Bio/motifs/__init__.py:            dict((k, "" if v is False else str(v)) for k, v in kwds.items()))
biopython//Bio/phenotype/phen_micro.py:        self._rows = sorted(set(x[0] for x in self._wells))
biopython//Bio/phenotype/phen_micro.py:        self._columns = sorted(set(x[1:] for x in self._wells))
```

I think these can be updated now since Python 2.6 is not supported by Biopython? 

Most of these can be fixed very easily, but finding the examples will require some checking since I don't think there is an obvious pattern to match here given the comprehensions can be multi-line etc.


Discussion:
Yes.
Yes, it does seem timely to fix these. This flake8 plugin will help finding them,

https://github.com/adamchainz/flake8-comprehensions

Specifically your example triggers:

```
C402 Unnecessary generator - rewrite as a dict comprehension.
```

All the codes from this plugin start with C4, e.g.

```
$ flake8 --isolated --select C4 BioSQL/
BioSQL/BioSeq.py:372:23: C401 Unnecessary generator - rewrite as a set comprehension.
BioSQL/Loader.py:915:22: C401 Unnecessary generator - rewrite as a set comprehension.
BioSQL/Loader.py:915:58: C405 Unnecessary list literal - rewrite as a set literal.
```

(Lots more elsewhere in the codebase)
Ok- i'll work on this via the flake8 plugin, which will also capture a few other things like the set literal example Peter has above
I found some of these hard to get used to, having written so much Python the "old fashioned" way.

Resolving patch:
diff --git a/Scripts/Restriction/ranacompiler.py b/Scripts/Restriction/ranacompiler.py
--- a/Scripts/Restriction/ranacompiler.py
+++ b/Scripts/Restriction/ranacompiler.py
@@ -323,6 +323,8 @@ def buildtype(self):
                     dct.update({'scd5': None, 'scd3': None})
 
             class klass(type):
+                """Dynamically defined restriction enzyme class."""
+
                 def __new__(cls):
                     return type.__new__(cls, 'type%i' % n, ty, dct)
 
@@ -405,7 +407,7 @@ def build_dict(self):
             #   Now select the right type for the enzyme.
             #
             bases = cls.bases
-            clsbases = tuple([eval(x) for x in bases])
+            clsbases = tuple([eval(x) for x in bases])  # noqa: C407
             typestuff = ''
             for t in tdct.values():
                 #
@@ -432,7 +434,7 @@ def build_dict(self):
             else:
                 enzlst = []
                 tydct = dict(typestuff.__dict__)
-                tydct = dict([(k, v) for k, v in tydct.items()
+                tydct = dict([(k, v) for k, v in tydct.items()  # noqa: C404
                               if k in commonattr])
                 enzlst.append(name)
                 typedict[typename] = (bases, enzlst)


Test patch: