Package: lenses
Lenses is a python library that helps you to manipulate large
data-structures without mutating them. It is inspired by the lenses in
Haskell, although it’s much less principled and the api is more suitable
for python.InstallationYou can install the latest version from pypi using pip like so:pip install lensesYou can uninstall similarly:pip uninstall lensesDocumentationThe lenses library makes liberal use of docstrings, which you can access
as normal with thepydocshell command, thehelpfunction in
the repl, or by reading the source yourself.Most users will only need the docs fromlenses.UnboundLens. If you
want to add hooks to allow parts of the library to work with custom
objects then you should check out thelenses.hooksmodule. Most of
the fancy lens code is in thelenses.opticsmodule for those who
are curious how everything works.Some examples are given in theexamplesfolder and thedocumentationis available on ReadTheDocs.Example>>>frompprintimportpprint>>>fromlensesimportlens>>>>>>data=[{'name':'Jane','scores':['a','a','b','a']},...{'name':'Richard','scores':['c',None,'d','c']},...{'name':'Zoe','scores':['f','f',None,'f']}]...>>>format_scores=lens.Each()['scores'].Each().Instance(str).call_upper()>>>cheat=lens[2]['scores'].Each().set('a')>>>>>>corrected=format_scores(data)>>>pprint(corrected)[{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},
 {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},
 {'name': 'Zoe', 'scores': ['F', 'F', None, 'F']}]>>>>>>cheated=format_scores(cheat(data))>>>pprint(cheated)[{'name': 'Jane', 'scores': ['A', 'A', 'B', 'A']},
 {'name': 'Richard', 'scores': ['C', None, 'D', 'C']},
 {'name': 'Zoe', 'scores': ['A', 'A', 'A', 'A']}]The definition offormat_scoresmeans “for each item in the data take
the value with the key of'scores'and then for each item in that list
that is an instance ofstr, call itsuppermethod on it”. That one
line is the equivalent of this code:defformat_scores(data):results=[]forentryindata:result={}forkey,valueinentry.items():ifkey=='scores':new_value=[]forletterinvalue:ifisinstance(letter,str):new_value.append(letter.upper())else:new_value.append(letter)result[key]=new_valueelse:result[key]=valueresults.append(result)returnresultsNow, this code can be simplified using comprehensions. But comprehensions
only work with lists, dictionaries, and sets, whereas the lenses library
can work with arbitrary python objects.Here’s an example that shows off the full power of this library:>>>fromlensesimportlens>>>state=(("foo","bar"),"!",2,())>>>lens.Recur(str).Each().Filter(lambdac:c<='m').Parts().call_mut_reverse()(state)(('!oo', 'abr'), 'f', 2, ())This is an example from thePutting Lenses to Worktalk about the
haskell lenses library by John Wiegley. We extract all the strings inside
ofstate, extract the characters, filter out any characters that
come after'm'in the alphabet, treat these characters as if they
were a list, reverse that list, before finally placing these characters
back into the state in their new positions.This example is obviously very contrived, but I can’t even begin to
imagine how you would do this in python code without lenses.Licensepython-lenses is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.You should have received a copy of the GNU General Public License along
with this program. If not, seehttp://www.gnu.org/licenses/.