How to add a key,value pair to a list? - python

I would like to be able to create a list of key, list pairs ( I think that's the most accurate way to describe my desired solution...)
I have a list of dictionaries and would like to add an element to each of these dictionaries that is a list of dictionaries (a mouthful, I know...).
To do this, I try to append key, value pairs to a list. When I do this I get a syntax error ostensibly tripped on the colon in the key:value pair.
Here's my code:
d_l[0]['abilities'] = list()
d_l[0]['abilities'].append(abilities_m_l[job_row]['Element Name']:list()) # ability: stats about ability
where d_l is a list of dictionaries, 'abilities' is a key that I am creating.
And here's my error (the caret is on the colon (although in the past it's mislabeled the location of the error)).
d_l[0]['abilities'].append(abilities_m_l[job_row]['Element Name']:list()) # ability: stats about ability
^
SyntaxError: invalid syntax
logout
If it helps, this is the desired overall structure:
{
'job':'clerk', 'description': 'works in a bank', 'abilities': [
'math': [
'imp': {
'Data Value': 4.5,
'N' : 8,
'S_E': 0.19
},
'level': {
'Data Value': 4.75,
'N': 8,
'S_E': 0.25
}
],
'english': [
'imp': {
},
'level': {
}
],
'dexterity': [
'imp':{
},
'level': {
}
]
]
},
Thanks so much! If you see obvious flaws in my arrangement just above (maybe I should be using a dictionary for abilities instead of a list?) please let me know.

You want to append a dict - note the {}, eg:
.append( {abilities_m_l[job_row]['Element Name']:list()} )
And it's more Pythonic and efficient to use [] for an empty list...

Related

shorter way to delete key from a dictionary

I have wanted to delete the taste key from the line_items dict list of the entire dictionary list. the code is given below
orders = [
{
'order_id' : 1,
'line_items': [
{
'product_id': 2,
'product_name' : 'mango',
'taste' : 'sweet',
},
{
'product_id':3,
'product_name': 'grape',
'taste': 'sweet & sour',
}
],
},
{
'order_id' : 2,
'line_items': [
{
'product_id': 4,
'product_name' : 'lime',
'taste' : 'sour',
}
]
},
]
I have already done it. and this is my solution.
delitems = ['taste']
for order in orders:
for item in order["line_items"]:
for delkeys in delitems:
item.pop(delkeys)
But I think it is a bad code and wanted to know if is there any way to shorting my code
with dict comprehension or another way?
Slightly more natural than using dict.pop when you don't care about the value you're deleting would be to use the del statement:
del item[delkeys]
Obviously, this doesn't reduce the number of lines. If you're only ever deleting the one key, you don't need the delitems and the loop over it. If you don't mind hard-coding that "taste" is the key to delete, just do:
for order in orders:
for item in order["line_items"]:
del item["taste"]
While you could write a bunch of nested list comprehension and dictionary comprehensions to achieve the same effect in a single statement, it would be a lot harder to understand than your simple nested loop code.
for order in orders:
for item in order["line_items"]:
del item["taste"]

How to sort dictionary with keys, using certain field in dict - Python 3

second try for this question. I already changed 2 suggested answers, but they didn't solved my problem.
My dictionary looks like this:
old_list = {
"x": {
"bd_date": "04/01/1977",
"name": "Deli Mirko",
"next": "04/02/2021",
"renew": 1,
"type": "birthday",
"until": 335
},
"y": {
"bd_date": "25/11/1983",
"name": "Deli Marina",
"next": "25/11/2021",
"renew": 1,
"type": "birthday",
"until": 295
},
.....
}
I wish to sort it using "until" values ASC.
Is there a way to do this.
I tried suggested solutions,
Sort nested dictionary by values
Sort nested dictionary by value, and remainder by another value, in Python
but I don't get result OR it changes my dictionary format. I need to keep format, because the rest of code.
I tried
new_list = sorted(old_list.items(), key=lambda i: i[1]['until'])
but it changes format to list from dict - [("x",{...}), ("y",{..})...]
So, how to change above code to keep format {"x": {...}, "y": {...}}
This is important because later in code I use loop that outputs data
events_keys = old_list.keys()
for events_key in events_keys:
event = old_list[events_key]
# Get values for each event
tmp_bd = event['bd_date']
tmp_name = event['name']
....
so I guess I need to sort dict first, so printed values come in increasing order?!
Just use dictionary comprehension on your sort result. This works since from Python 3.6 onwards, the standard dict type maintains insertion order by default.
new_list = {k:v for k, v in sorted(old_list.items(), key=lambda i: i[1]['until'])}
new_list:
{'y': {'bd_date': '25/11/1983',
'name': 'Deli Marina',
'next': '25/11/2021',
'renew': 1,
'type': 'birthday',
'until': 295},
'x': {'bd_date': '04/01/1977',
'name': 'Deli Mirko',
'next': '04/02/2021',
'renew': 1,
'type': 'birthday',
'until': 335}}

How can I mitigate the error in Python Dictionary?

How do I access to visibilities?
I am trying like this: dev1['data']['results :visibilites ']
dev1 = {
"status": "OK",
"data": {
"results": [
{
"tradeRelCode": "ZT55",
"customerCode": "ZC0",
"customerName": "XYZ",
"tier": "null1",
"visibilites": [
{
"code": "ZS0004207",
"name": "Aabc Systems Co.,Ltd",
"siteVisibilityMap": {
},
"customerRef": "null1"
}
]
}
],
"pageNumber": 3,
"limit": 1,
"total": 186
}
}
You can use dev1['data']['results'][0]['visibilites'].
It will contain a list of one dictionary.
To access this dictionary directly, use dev1['data']['results'][0]['visibilites'][0]
dev['data'] represents a dictionary that has for key results.
You can access the item associated to results key (a list) using (dev1['data'])['results'].
To access the only member of this list, you use ((dev1['data'])['results'])[0].
This gives you a dictionary that has tradeRelCode, customerCode, customerName, tier and visibilites keys.
To access the item associated to visibilites key (a list), you have tu use (((dev1['data'])['results'])[0])['visibilites'].
To finally access the only dictionary contained in this list, you have tu use ((((dev1['data'])['results'])[0])['visibilites'])[0].
Parenthesis are here to show that python dig into each dictionary or list in order from left to right (python does not mind the parenthesis in the code, you can keep them if it is clearer for you.)
In your data structure use path
dev1['data']['results'][0]['visibilites']
Try this
dev1['data']['results'][0]['visibilites']
Reason:
This is a list -> dev1['data']['results']
So, access this -> dev1['data']['results'][0]
and then you obtain this ->
{'tradeRelCode': 'ZT55',
'customerCode': 'ZC0',
'customerName': 'XYZ',
'tier': 'null1',
'visibilites': [{'code': 'ZS0004207',
'name': 'Aabc Systems Co.,Ltd',
'siteVisibilityMap': {},
'customerRef': 'null1'}]}
and then you can have -> dev1['data']['results'][0]['visibilites']
which results in ->
[{'code': 'ZS0004207',
'name': 'Aabc Systems Co.,Ltd',
'siteVisibilityMap': {},
'customerRef': 'null1'}]
which is a list and you can index the first element which is another dictionary

How to fetch a matching record from an array in python?

I've a following array in python. I want to retrieve the record with an id. Is there a way to do it other than checking id field of each record by iterating through all the records. Is there a better way to do it ?
[
{
'id': 'zy0Wk',
'name': 'vendor_change_order_status.txt',
'path': 'templates/messages/vendor_change_order_status.txt'
},
{
'id': 'JTo8c',
'name': 'vendor_change_order_status_accepted.txt',
'path': 'templates/messages/vendor_change_order_status_accepted.txt'
},
]
If you're just doing a single lookup, there's really nothing better than checking record by record.
But if you're going to do a lot of lookups on the same data, you want to transform that list into a dict, keyed by the ids:
lst = [
{
'id': 'zy0Wk',
'name': 'vendor_change_order_status.txt',
'path': 'templates/messages/vendor_change_order_status.txt'
},
{
'id': 'JTo8c',
'name': 'vendor_change_order_status_accepted.txt',
'path': 'templates/messages/vendor_change_order_status_accepted.txt'
},
]
dct = {element['id']: element for element in lst}
Now, you can look things up a lot more simply:
thingy = dct['JTo8c']
And it's also a lot more efficient. Looking things up in a list takes linear time—you have to compare it to every element in the list. Looking things up in a hash table (what a dict uses under the covers) takes constant time—you hash it, and you do a single compare, and you know that it's either there, or not there.1
1. This isn't quite true, because different keys can have equal hashes. But if you expand the dictionary whenever you have too many collisions, you end up with amortized constant-time cost, and Python does that for you automatically.
You can use list comprehension:
filtered_list = [i for i in my_list if i.get('id') == 'zy0Wk']
Although this record is compact, it's also use iteration over your list.
Supposing you could modify the object that's being returned, you might be better structuring it as a dictionary of dictionaries like so:
my_list = {
'zy0Wk': {
'name': 'vendor_change_order_status.txt',
'path': 'templates/messages/vendor_change_order_status.txt'
},
'JTo8c': {
'name': 'vendor_change_order_status_accepted.txt',
'path': 'templates/messages/vendor_change_order_status_accepted.txt'
}
}
You can then retrieve the values for an id by doing the following:
>>> my_record = my_list['zy0Wk']
>>> print(my_record)
{'path': 'templates/messages/vendor_change_order_status.txt', 'name': 'vendor_change_order_status.txt'}
If you need this action only once than the answer is no. But if you need to do this retrieving a lot of times you can construct a dictionary and use id as key:
a = [
{
'id': 'zy0Wk',
'name': 'vendor_change_order_status.txt',
'path': 'templates/messages/vendor_change_order_status.txt'
},
{
'id': 'JTo8c',
'name': 'vendor_change_order_status_accepted.txt',
'path': 'templates/messages/vendor_change_order_status_accepted.txt'
},
]
d = {x["id"]:x for x in a}
print(d["zy0Wk"])
print(d["JTo8c"])

Modify nested value in a dictionary

Consider this dictionary shown below:
"Title": {
"Label-1": {
"sublabel-1": {
"item1": {},
"item2": {}
},
"sublabel-2": {
"item3": {},
"item4": {},
"item5": {}
}
}
"Label-2": {
"sublabel-1": {
"item6": {},
"item7": {},
"item8": {},
}
}
}
Here is a dictionary to modify some key-value pairs as shown below.
values_to_add={item1:a,item2:b}
The goal is to add values a and b to the respective keys in the dictionary.
For reference, I read the following posts:
1.First Reference:
(The difference is that I just have the key-value pair to modify and not the detailed trail upto the key-value pair as given in the update variable.)
2.Second Reference:
(Unfortunately, no follow up on the question.)
Some additional points:
Level and depth of dictionary may vary. The main focus would be to add values to the innermost keys for any sublabel most of the times.(in this case item1 and item2)
Using python 2 to manipulate the dictionary.
I am currently trying to create a program to work it out. Hopefully looking to get some insights on different approaches to the problem and learn something new.
It looks like your data structure reflects the way you want to output the data, and that is complicating the update process.
Postpone the construction of your nested dictionary. Instead, set up flat a dictionary with only the leaf keys, and the superordinate keys as data:
{
"item1": {'path': ("Title","Label-1","sublabel-1"), "values":{} },
"item2": {'path': ("Title","Label-1","sublabel-1"), "values":{} },
"item3": {'path': ("Title","Label-1","sublabel-2"), "values":{} },
"item4": {'path': ("Title","Label-1","sublabel-2"), "values":{} },
"item5": {'path': ("Title","Label-1","sublabel-2"), "values":{} },
"item6": {'path': ("Title","Label-2","sublabel-1"), "values":{} },
"item7": {'path': ("Title","Label-2","sublabel-1"), "values":{} },
"item8": {'path': ("Title","Label-2","sublabel-1"), "values":{} },
}
When it is complete you can iterate through it and construct the nested structure you want. This also allows you to easily accommodate key paths of varying lengths, which would otherwise make for a very complex access method.
This does of course assume your leaf keys are unique. That was also implicit in your question. It does strike me as an unlikely assumption in practice, though.

Categories