1

Say I have a list of filenames files containing data in json format. To receive the data in a list with an entry for each file, I use a list comprehension:

>>> import json
>>> data = [json.load(open(file)) for file in files]

Now I was wondering, if there is a way to append the file name file to the json data, as if it looked like this:

{
  'Some': ['data', 'that', 'has', 'already', 'been', 'there'],
  'Filename': 'filename'
}

For my case, json.load() returns a dict, so I've tried something similar to this question. This didn't work out for me, because files contains strings and not dictionaries.

Edit

For clarification, if dict.update() didn't return None, this would probably work:

>>> data = [dict([('filename',file)]).update(json.load(open(file))) for file in files]
jpp
  • 159,742
  • 34
  • 281
  • 339
KorbenDose
  • 797
  • 1
  • 7
  • 23

2 Answers2

2

Yes, you can. Here's one way (requires Python 3.5+):

import json

data = [{**json.load(open(file)), **{'Filename': file}} for file in files]

The syntax {**d1, **d2} combines 2 dictionaries, with preference for d2. If you wish to add items explicitly, you can simply add an extra item as so:

data = [{**json.load(open(file)), 'Filename': file} for file in files]
jpp
  • 159,742
  • 34
  • 281
  • 339
  • You don't need to make the inner temp `dict` for the filename just to unpack it immediately, `{**json.load(open(file)), 'Filename': file}` will work just fine. – ShadowRanger Jun 12 '18 at 14:17
  • @ShadowRanger, Good point. In this case, your option is cleaner. – jpp Jun 12 '18 at 14:18
  • 1
    It's extendable either way; you can seamlessly mix definitions of individual key/value pairs with the unpacking existing dicts. `{'a': 1, **x, 'b': 2, 'c': 3, **y}` is perfectly legal, and you can add individual elements on as needed. – ShadowRanger Jun 12 '18 at 14:21
2

You can merge a custom dictionary into the one being loaded as in this answer.

data = [{**json.loads("{\"el...\": 5}"), **{'filename': file}} for file in files]
ritlew
  • 1,622
  • 11
  • 13