Reputation: 557
I'm creating a table like this:
data = json.load(f)
num_of_certificates = (len(data.get('certificates')))
new_data = sorted([{n: f"{data.get('certificates', [{}])[i].get(n, 0)}"
for n in some_dic}
for i in range(num_of_items)], key=lambda x: (int(x['exp_date_year']), int(x['exp_date_month']), int(x['exp_date_day'])))
and I want to add an extra item. Imagine having one more "n" to loop through but I can't just add it in the "some_dic" for my reasons that dont affect this. I tried
data = json.load(f)
num_of_certificates = (len(data.get('certificates')))
new_data = sorted([{n: f"{data.get('certificates', [{}])[i].get(n, 0)}",
'test': 'test value'
for n in some_dic}
for i in range(num_of_items)], key=lambda x: (int(x['exp_date_year']), int(x['exp_date_month']), int(x['exp_date_day'])))
but it doesn't work. I made it work doing it like this:
data = json.load(f)
num_of_certificates = (len(data.get('certificates')))
new_data = sorted([{n: f"{data.get('certificates', [{}])[i].get(n, 0)}" if n is not "remaining_days" else "new_value"
for n in some_dic}
for i in range(num_of_certificates)], key=lambda x: (int(x['exp_date_year']), int(x['exp_date_month']), int(x['exp_date_day'])))
basically adding another empty thing inside "some_dic" but this creates other issues and I feel like there's a way easier way to do this. Here's the "some_dic" dictionary
some_dic = {
"name": False,
"type": False,
"exp_date_day": False,
"exp_date_month": False,
"exp_date_year": False,
"color": False,
"remaining_days": True
}
Here's the json file im parsing:
{
"certificates": [
{
"exp_date_year": "2020",
"name": "1",
"type": "1",
"exp_date_day": "1",
"exp_date_month": "1",
"color": "1",
"exp_date_day_of_year": 1
},
{
"exp_date_year": "2020",
"name": "2",
"type": "2",
"exp_date_day": "2",
"exp_date_month": "2",
"color": "2",
"exp_date_day_of_year": 33
},
{
"exp_date_year": "2022",
"name": "3",
"type": "3",
"exp_date_day": "3",
"exp_date_month": "3",
"color": "3",
"exp_date_day_of_year": "62"
}
]
}
Upvotes: 0
Views: 59
Reputation: 8180
First, you should probably une regular loops to avoid an overcomplicated expression like this.
Second, your f-string make no sense:
f"{data.get('certificates', [{}])[i].get(n, 0)}"
is the same as:
str(data.get('certificates', [{}])[i].get(n, 0))
Third, you can replace:
[{n: str(data.get('certificates', [{}])[i].get(n, 0)})
for n in some_dic}
for i in range(num_of_items)]
By:
[{n: str(c.get(n, 0)})
for n in some_dic}
for c in data.get('certificates', [{}])]
Because c
will iterate over the elements of data['certificates']
.
Fourth, since you are using only the keys of some_dic
, you can write:
some_keys = {"name", "type", "exp_date_day", "exp_date_month", "exp_date_year", "color"}
L = [{n: str(c.get(n, 0)})
for n in some_keys}
for c in data.get('certificates', [{}])]
new_data = sorted(L, ...)
Fifth, I would test if certificates
is in data
before the list comprehension.
Note that you return an empty list if data['certificates']
is an empty list
or if the key certificates
is not in data
. I would rather raise an error in the second case:
if 'certificates' not in data:
raise ValueError("Data is corrupted")
certificates = data['certificates']
L = [{k: str(c.get(n, 0)}) for k in some_keys} for c in certificates]
...
And sixth, the actual answer to your question, you want to add an element to the dict in one expression. See this question and the answers:
L = [{**{k: str(c.get(n, 0)}) for k in some_keys}, 'remaining_days': 'new_value'} for c in certificates]
Again, prefer regular loops unless this part of your code is a bottleneck.
Upvotes: 1