0

I am trying to parse a bibtex file with python3's bibtexparser module.

A sample bibtex file is:

@article{ebert2013,
  Title={First-principles calculation of the Gilbert damping parameter via the linear response formalism with application to magnetic transition metals and alloys},
  Author={Mankovsky, S. and K{\"o}dderitzsch, D. and Woltersdorf, G and Ebert, H.},
  Volume={87},
  Pages={1},
  Year={2013},
  Journal={Phys. Rev. B}
}
@article{ebert2011,
  title = {\textit{Ab Initio} Calculation of the Gilbert Damping Parameter via the Linear Response Formalism},
  author = {Ebert, H. and Mankovsky, S. and K{\"o}dderitzsch, D. and Kelly, P. J.},
  journal = {Phys. Rev. Lett.},
  volume = {107},
  pages = {066603},
  month = {Aug},
  publisher = {American Physical Society}
}
@article{paudyal2013,
  author={Narayan Poudyal and J Ping Liu},
  title={Advances in nanostructured permanent magnets research},
  journal={Journal of Physics D: Applied Physics},
  volume={46},
  number={4},
  pages={043001},
  year={2013}
}

Note See the 2nd item does not have any year key.

Now, I am trying to parse this file as:

    import bibtexparser
    from bibtexparser.bparser import BibTexParser
    # from bibtexparser.bwriter import BibTexWriter
    from bibtexparser.bibdatabase import BibDatabase

    db = BibDatabase()
    with open('report.bib') as bibtex_file:
        parser = BibTexParser()
        db = bibtexparser.load(bibtex_file, parser=parser)
        for i in range(0, len(db.entries)):
            try:
                tuples = (db.entries[i]["title"],db.entries[i]["author"],
                         db.entries[i]["journal"],db.entries[i]["year"])
            except(KeyError):
                continue
            print(tuples)

Since, it does not find the year entry, it is skipping the 2nd element all together; giving output as:

('First-principles calculation of the Gilbert damping parameter via the linear\nresponse formalism with application to magnetic transition metals and alloys', 'Mankovsky, S. and K{\\"o}dderitzsch, D. and Woltersdorf, G and Ebert, H.', 'Phys. Rev. B', '2013')
('Advances in nanostructured permanent magnets research', 'Narayan Poudyal and J Ping Liu', 'Journal of Physics D: Applied Physics', '2013')

But, the desired behaviour is to get the entry with a NULL value for the missing item.

How I can do that?

I have actually gone through this and this se question among others, but have not gained much.

Kindly help.

Community
  • 1
  • 1
BaRud
  • 3,055
  • 7
  • 41
  • 89
  • can't you also just iterate on db.entries instead of using for i in range + len.... ? if yes it would be way cleaner ;-) for entry in db.entries: ...entry.get('title'), entry.get('author'), entry.get('journal'), entry.get('year') – DevLounge Jan 17 '16 at 20:23

1 Answers1

3

use .get, and you can remove your try/except for KeyError as well

db.entries[i].get("year")

With dictionaries, it is often recommended to use dict.get(<key>, default=None), to prevent KeyError exceptions, while iterating on non-sanitized data.

Also have a look to dict.pop(<key>, default) which also prevents exceptions but forces you to provide a default value.

DevLounge
  • 8,313
  • 3
  • 31
  • 44