boop boop - 1 month ago 6
Python Question

Build a dictionary using select values from a different dictionary

I have a dictionary with years as keys and other dictionaries as values (these inner dictionaries contain tuples (i, i+1) as keys). An example of the format would be:

myDict = {2000: {(0,1):111.1, (1,2):222.2, (2,3):333.3, (3,4):444.4}
2001: {(0,1):11.1, (1,2):22.2, (2,3):33.3, (3,4):44.4}}


From this dictionary, I am trying to compile a dictionary,
secondDict
, that also has years for keys. The values will be the sum of the innermost values in
myDict
for only certain tuples (i.e. any tuple in that year whose 0th index is greater than 1). What I am going for is a dictionary that looks like this:

secondDict = {2000: 777.7, 2001: 77.7}


The value in
secondDict
would be the sum of the values in
myDict[2000][tuple]
if the 1st number in the tuple was greater than or equal to
2
.

So far I have:

years = [2000, 2001, 2002, 2003, 2011, 2012, 2013, 2014]
tuples = [(i, i+1) for i in range(65)]

for year in years:
for key in myDict[year]:
for value in myDict[year][key]:
if key[0] >= 30:
secondDict[year] += value


I have several problems with my method here, but can't think of another way to build the dictionary.

1) Firstly, I'm getting a
TypeError: 'float' object is not iterable
for the third line of the loop (
for value in
...). All the values that I am trying to access are floats, so I'm not sure how to work around this.

2) Moving on to problems I anticipate but haven't been able to address due to the
TypeError
: In the line
if key[0] >= 30
I am trying to access the 0th index of the tuple; will this work / if not, how do I access it?

3) I am working with some fairly large dictionaries here and it seems like the running time for this many loops will be quite slow; however I'm pretty new to coding so my grasp of this is limited. Is it just O(n) for each loop, i.e. O(n^4) since there are four loops? How can I create a better, quicker algorithm to build a dictionary like this?

EDIT:

After more research and some finicking with the code, I now have:

for year in years:
for key in myDict[year].keys():
if key[0] >= 30:
secondDict[year] += myDict[year][key]


This doesn't raise any errors, but upon printing it I find that it only compiles for one year:

In[5]: secondDict
Out[5]:
defaultdict(None,
{2000: 0,
2001: 0,
2002: 0,
2003: 27162828.602349777,
2011: 0,
2012: 0,
2013: 0,
2014: 0})


Why is it not iterating fully over
years
? Any suggestions?

Answer

Here's a dict comprehension that performs the action you specify at the start of your question, i.e., the values are the sum of the innermost values in myDict for tuples whose 0th index is greater than 1.

myDict = {
    2000: {(0,1):111.1, (1,2):222.2, (2,3):333.3, (3,4):444.4},
    2001: {(0,1):11.1, (1,2):22.2, (2,3):33.3, (3,4):44.4},
}

secondDict = {y: sum(v for t, v in d.items() if t[0] > 1) 
    for y, d in myDict.items()}
print(secondDict)

output

{2000: 777.7, 2001: 77.69999999999999}
Comments