Search code examples
pythonlistdictionarytypesitems

.items() reading a dictionary as a list and throwing an attribute error


I am using IN-CORE, a analysis platform for natural disasters. I am working with a Monte Carlo definition in their library (pyincore). I am using this code to run through a list of dictionary entries of damage states for different infrastructure locations.

failure = []
for i in range(10):
    print(damages[i]) # prints {'DS_0': Decimal('0.6716138851'), 'DS_1': 0, 'DS_2': 0, 'DS_3': Decimal('0.3283861149')}

    print(damages[i].items()) # prints dict_items([('DS_0', Decimal('0.6716138851')), ('DS_1', 0), ('DS_2', 0), ('DS_3', Decimal('0.3283861149'))])
    damage_interval_keys = ["DS_0" , "DS_3"]
    failure_state_keys = ["DS_3"]
    (MonteCarloFailureProbability.calc_probability_failure_value(damages[i], damage_interval_keys, failure_state_keys))
    
print(failure)

However, I get this error:

AttributeError                            Traceback (most recent call last)
Cell In[167], line 9
      7     damage_interval_keys = ["DS_0" , "DS_3"]
      8     failure_state_keys = ["DS_3"]
----> 9     (MonteCarloFailureProbability.calc_probability_failure_value(damages[i], damage_interval_keys, failure_state_keys))
     11 print(failure)

File ~\AppData\Local\miniconda3\envs\pyincoreEnv\lib\site-packages\pyincore\analyses\montecarlofailureprobability\montecarlofailureprobability.py:329, in MonteCarloFailureProbability.calc_probability_failure_value(self, ds_sample, failure_state_keys)
    327 count = 0
    328 func = {}
--> 329 for sample, state in ds_sample.items():
    330     if state in failure_state_keys:
    331         func[sample] = "0"

AttributeError: 'list' object has no attribute 'items'

I made sure the list of the dict entries wasn't layered in another list, but as the code above prints, the .items() works outside of the function call and the .dtype returns that the list at a certain index is a dictionary. I am quite confounded, so any help would be amazing.


Solution

  • Since you're calling the method on the class, rather than an instance, the first argument is being used as self, not ds_sample, and the list damage_interval_keys is being used as ds_sample.

    Create an instance of the class first, and call the method on that.

    sim = MonteCarloFailureProbability()
    failure = []
    for i in range(10):
        print(damages[i]) # prints {'DS_0': Decimal('0.6716138851'), 'DS_1': 0, 'DS_2': 0, 'DS_3': Decimal('0.3283861149')}
    
        print(damages[i].items()) # prints dict_items([('DS_0', Decimal('0.6716138851')), ('DS_1', 0), ('DS_2', 0), ('DS_3', Decimal('0.3283861149'))])
        damage_interval_keys = ["DS_0" , "DS_3"]
        failure_state_keys = ["DS_3"]
        (sim.calc_probability_failure_value(damages[i], damage_interval_keys, failure_state_keys))
        
    print(failure)
    

    There's other problems, though -- you're printing failure at the end, but nothing updates that. Are you missing a call to failure.append() with the results of the call?