The {**row}
just unpacks the dictionary (which is allowed in literals in python-3.5+):
>>> row = {'DBA Name': "make 'this' now", 'b': 2}
>>> {**row}
{'DBA Name': "make 'this' now", 'b': 2}
Essentially this just makes a copy of row
because you unpack a dictionary into a dictionary.
The second part is normal dictionary literal syntax:
>>> {'DBA Name': row['DBA Name'].replace("'",'').upper() }
{'DBA Name': 'MAKE THIS NOW'}
The "magic" bit is that dictionaries map unique keys to some value, so this is essentially a copy the row
dictionary and replaces the 'DBA Name'
key with the new value. That works because literals are interpreted from left to right:
>>> { **row, 'DBA Name': row['DBA Name'].replace("'",'').upper() }
{'DBA Name': 'MAKE THIS NOW', 'b': 2}
Normally you would just create a copy of the dictionary and replace the key:
>>> newrow = row.copy()
>>> newrow['DBA Name'] = row['DBA Name'].replace("'",'').upper()
But that doesn't work in comprehensions (assignment inside comprehensions is a SyntaxError
) so you need some "magic" (or invoke special methods).
But you could also do it with a nested comprehension (it's slower but maybe less magic):
[ k: v.replace("'",'').upper() if key == 'DBA Name' else v
for row in fail
for k, v in row.items()]
The indentation may seem a bit off but I find it easier to visualize this way, you could also use just one line:
[k: v.replace("'",'').upper() if key == 'DBA Name' else v for row in fail for k, v in row.items()]