Creating multiple keys dictionaries from lists - python

I was using pyomo and I have to create some dictionaries with multiple keys to work with it.
So, for example, I have these three lists below, and I want to associate Demand with both Product and Client.
They're already ordered and contain the same amount of entries.
Product = ["A","B","C","A","B","C"]
Client = ["Client1","Client1","Client1","Client2","Client2","Client2"]
Demand = [1,2,3,4,5,6]
And so I wanted the following output:
Demand_dict = {("A","Client1"):1, ("B","Client1"):2,("C","Client1"):3,("A","Client2"):4, ("B","Client2"):5,("C","Client2"):6,
I tried usind dict(zip) but I can't put multiple keys on th first argument.
Any easy way of doing it?
Thanks

This should give you the result you need using a dictionary comprehension:
Demand_dict = {(p, c): d for p, c, d in zip(Product, Client, Demand)}
It zips the three lists and then iterates over the 3-tuples using the first two values as the key for a dictionary entry and the third value as the value.

Related

Finding two list in a dictionary with the most distinct values

I have a dictionary with a form key:list where key is a name of a student and list is a list of every proffesor of theirs. I need to find two keys(students) with the most distinct values(teachers) in their lists. So basically I need to find the largest intersection.
This is the dictionary I need to work with: https://github.com/kXtof/python3learningprojects/blob/main/find_intersect_of_two_lists/dict_student_teacher
If there is more than one pair with the same amount of dictinct teachers, I can choose which pair I will print.
>>> max(itertools.combinations(d, 2),
key=lambda p: len(set(d[p[0]]) & set(d[p[1]])))
('WMXZFQJGJT', 'SMELGPEIOP')

How can I pair 2 data types together in python?

Lets say I have a list called pair
I want it to contain a pair of strings and boolean values like
pair = [(a,True), (b,False), (c,False)] and so on. I just found out about tuples and wanted to use them for this purpose but they're immutable which is a bummer because I have to add and remove data later. How else could I achieve this? Later, I'd like to process the pairs eg if a is True: do this
Just use lists if you need mutability:
pair = [[a,True], [b,False], [c,False]]
And then you can change items in this way:
pair[0][1] = False
You can use dict:
pari_dict = dict(pair)
if pari_dict[a]:
#do this

Adding two asynchronous lists, into a dictionary

I've always found Dictionaries to be an odd thing in python. I know it is just me i'm sure but I cant work out how to take two lists and add them to the dict. If both lists were mapable it wouldn't be a problem something like dictionary = dict(zip(list1, list2)) would suffice. However, during each run the list1 will always have one item and the list2 could have multiple items or single item that I'd like as values.
How could I approach adding the key and potentially multiple values to it?
After some deliberation, Kasramvd's second option seems to work well for this scenario:
dictionary.setdefault(list1[0], []).append(list2)
Based on your comment all you need is assigning the second list as a value to only item of first list.
d = {}
d[list1[0]] = list2
And if you want to preserve the values for duplicate keys you can use dict.setdefault() in order to create value of list of list for duplicate keys.
d = {}
d.setdefault(list1[0], []).append(list2)

Create a list of an inner value from a dict of dicts

I am trying to figure out the max and min values for an inner value of a dict of dicts.
The dict looks like this:
{'ALLEN PHILLIP K': {'bonus': 4175000,
'exercised_stock_options': 1729541,
'expenses': 13868},
'BADUM JAMES P': {'bonus': 'NaN',
'exercised_stock_options': 257817,
'expenses': 3486},
...
}
I want to figure out the minimum and maximum exercised_stock_options across all dictionaries.
I tried using pandas to do this, but couldn't find a way to shape the data appropriately. Then, I tried a simple for-loop in Python. My code for the for-loop doesn't work, and I can't figure out why (the dict of dicts is called data_dict):
stock_options=[]
for person in range(len(data_dict)):
stock_options.append(data_dict[person]['exercised_stock_options'])
print stock_options
Then I was going to take the max and min values of the list.
Any idea why this code doesn't work? Any alternative methods for figuring out the max and min of an inner value of a dict of dicts?
Here's a method that uses a list comprehension to get the exercised_stock_options from each dictionary and then prints out the minimum and maximum value from the data. Ignore the sample data, and you can modify it to suit your needs.
d = {'John Smith':{'exercised_stock_options':99},
'Roger Park':{'exercised_stock_options':50},
'Tim Rogers':{'exercised_stock_options':10}}
data = [d[person]['exercised_stock_options'] for person in d]
print min(data), max(data)
You are using range to get an index number for your main dictionary. What you really should do is get the keys for the dictionary and not the index. That is, person is the name of each one. Thus when person == 'ALLEN PHILLIP K' datadict[person] now gets the dictionary for that key.
Note that the Use items() to iterate across dictionary says that it is better to use d, v = data_dict.items() rather than looping over the dictionary itself. Also note the difference between Python 2 and Python 3.
people=[]
stock_options=[]
for person, stock_data in data_dict.items():
people.append(person)
stock_options.append(stock_data['exercised_stock_options'])
# This lets you keep track of the people as well for future use
print stock_options
mymin = min(stock_options)
mymax = max(stock_options)
# process min and max values.
Best-practice
Use items() to iterate across dictionary
The updated code below demonstrates the Pythonic style for iterating
through a dictionary. When you define two variables in a for loop in
conjunction with a call to items() on a dictionary, Python
automatically assigns the first variable as the name of a key in that
dictionary, and the second variable as the corresponding value for
that key.
d = {"first_name": "Alfred", "last_name":"Hitchcock"}
for key,val in d.items():
print("{} = {}".format(key, val))
Difference Python 2 and Python 3
In python 2.x the above examples using items would return a list with
tuples containing the copied key-value pairs of the dictionary. In
order to not copy and with that load the whole dictionary’s keys and
values inside a list to the memory you should prefer the iteritems
method which simply returns an iterator instead of a list. In Python
3.x the iteritems is removed and the items method returns view objects. The benefit of these view objects compared to the tuples
containing copies is that every change made to the dictionary is
reflected in the view objects.
You need to iterate your dictionary .values() and return the value of "exercised_stock_options". You can use a simple list comprehensions to retrieve those values
>>> values = [value['exercised_stock_options'] for value in d.values()]
>>> values
[257817, 1729541]
>>> min(values)
257817
>>> max(values)
1729541
I've released lifter a few weeks ago exactly for these kind of tasks, I think you may find it useful.
The only problem here is that you have a mapping (a dict of dicts) instead of a regular iterable.
Here is an answer using lifter:
from lifter.models import Model
# We create a model representing our data
Person = Model('Person')
# We convert your data to a regular iterable
iterable = []
for name, data in your_data.items():
data['name'] = name
iterable.append(data)
# we load this into lifter
manager = Person.load(iterable)
# We query the data
results = manager.aggregate(
(Person.exercised_stock_options, min),
(Person.exercised_stock_options, max),
)
You can of course achieve the same result using list comprehensions, however, it's sometimes handy to use a dedicated library, especially if you want to filter data using complex queries before fetching your results. For example, you could get your min and max value only for people with less than 10000 expenses:
# We filter the data
queryset = manager.filter(Person.expenses < 10000)
# we apply our aggregate on the filtered queryset
results = queryset.aggregate(
(Person.exercised_stock_options, min),
(Person.exercised_stock_options, max),
)

Sorting list of dictionaries according to specific order

I am using Python 2.6 and I have two data stores. Querying the first one returns a list of document IDs in a specific order. I look up all the documents at once in the second data store using these IDs, which returns a list of dictionaries (one for each doc), but not in the same order as the original list. I now need to re-sort this list of dictionaries so that the documents are in the order that their IDs were in the first list. What's the best way of doing this?
Don't.
Move your "list of dictionaries (one for each doc), but not in the same order as the original list" into a dictionary.
This new dictionary-of-dictionaries has the matching key.
Then go through your first list in it's order and find items in the dictionary-of-dictionaries that match.
some_list= query_data_store_1()
some_other_list= query_data_store_2( some_list )
dict_of_dict = dict( (d['key'], d) for d in some_other_list )
for item in some_list:
other_item = dict_of_dict[ item['key'] ]
# Now you have item from the first list matching item from the second list.
# And it's in order by the first list.
You could build a separate dictionary mapping ids to positions and use that to order the documents:
ids = ...
positions = {}
for pos, id in enumerate(ids):
positions[id] = pos
docs = ...
docs.sort(key=lambda doc: positions[doc['id']])
The best (and general) solution seems to be given here: reordering list of dicts arbitrarily in python

Categories