Is there a faster way with do this? - python

So I'm doing a python project and I need to organize a list of values by dictionary. I would like to know if there's a faster way than just doing what I'm doing.
This is what I've done, is there a more efficient and easier way to do this?
def catogorize_by_mortality(hurricanes):
damage_scale = {0: 0, 1: 100, 2: 500, 3: 1000, 4: 1e4}
hurricane_mortality_dict = {0:[], 1:[], 2:[], 3:[], 4:[], 5:[]}
for hurricane in hurricanes:
current_hurricane = hurricanes[hurricane]
death_count = current_hurricane['Deaths']
if death_count > damage_scale[0] and death_count < damage_scale[1]:
hurricane_mortality_dict[0] += hurricane
elif death_count > damage_scale[1] and death_count < damage_scale[2]:
hurricane_mortality_dict[1] += hurricane
elif death_count > damage_scale[2] and death_count < damage_scale[3]:
hurricane_mortality_dict[2] += hurricane
elif death_count > damage_scale[3] and death_count < damage_scale[4]:
hurricane_mortality_dict[3] += hurricane
elif death_count >= damage_scale[4]:
hurricane_mortality_dict[4] += hurricane
else:
hurricane_mortality_dict[5] += hurricane
return hurricane_mortality_dict
# example of the hurricanes dictionary when printed
{'Cuba I': {'Name': 'Cuba I', 'Month': 'October', 'Year': 1924, 'Max Sustained Wind': 165, 'Areas Affected': ['Central America', 'Mexico', 'Cuba', 'Florida', 'The Bahamas'], 'Deaths': 90}
# this is what it returns
deaths.')
{0: ['C', 'u', 'b', 'a'
What's supposed to happen is that it will return the hurricane's names categorized but instead it splits them up into characters what's happening?

hurricane_mortality_dict[i] is defined as a list, near the top of the function:
hurricane_mortality_dict = {0:[], 1:[], 2:[], 3:[], 4:[], 5:[]}
So in your conditional, when you do hurricane_mortality_dict[i] += hurricane, you're trying to add a string and a list, which treats the string as a list of characters - hence your output.
All you need to do is change each:
hurricane_mortality_dict[i] += hurricane
to:
hurricane_mortality_dict[i].append(hurricane)
For your example input this then results in:
{0: ['Cuba I'], 1: [], 2: [], 3: [], 4: [], 5: []}

Related

Changing keys after loading json file dictionary

Okay, so I am having this issue with JSON, keys, and strings. I'm using a JSON dump in python to save my game dictionaries and it does work. The issue is when I load the dictionaries the game I'm making uses int values as keys in the world directory but JSON stores keys as strings. Here's a random generation I did.
worldmap = {
'Regions': {
1: 'Zelbridge', 2: 'Forest Path', 3: 'Baronbell', 4: 'Old Path', 5: 'Cariva', 6: 'Prairie Path'},
'Zelbridge': {1: 'Field', 2: 'Prairie Path', 3: 'School', 4: 'Mountain Path', 5: 'Graveyard',
6: 'Old Path', 7: 'Blacksmith', 8: 'Forest Path', 9: 'Doctor', 0: 'Zelbridge'},
'Forest Path': {1: 'Trees', 2: 'Bushes', 3: 'Path', 4: 'Cariva', 5: 'Path',
6: 'Baronbell', 7: 'Path', 8: 'Zelbridge', 9: 'Path', 0: 'Forest Path'},
'Baronbell': {1: 'House', 2: 'Mountain Path', 3: 'Graveyard', 4: 'Old Path', 5: 'Field',
6: 'Forest Path', 7: 'Church', 8: 'Prairie Path', 9: 'Shop', 0: 'Baronbell'},
'Old Path': {1: 'Path', 2: 'Trees', 3: 'Bushes', 4: 'Cariva', 5: 'Path',
6: 'Zelbridge', 7: 'Trees', 8: 'Baronbell', 9: 'Trees', 0: 'Old Path'},
'Cariva': {1: 'Cellar', 2: 'Old Path', 3: 'Graveyard', 4: 'Mountain Path', 5: 'Town Hall',
6: 'Prairie Path', 7: 'School', 8: 'Forest Path', 9: 'Blacksmith', 0: 'Cariva'},
'Prairie Path': {1: 'Bushes', 2: 'Path', 3: 'Path', 4: 'Zelbridge', 5: 'Trees',
6: 'Cariva', 7: 'Trees', 8: 'Baronbell', 9: 'Path', 0: 'Prairie Path'}
}
So when I use the load function I get key errors due to the int's being converted to strings. I attempted a for loop to iterate over the keys and change them back but I get this error about the dictionary changing. Here's an example of me trying to load a different (and also random) world. Its set to print after each loop showing that it works
What was your hero's name? #Input hero name
Loading...
{'2': 'Prairie Path', '3': 'Cariva', '4': 'Old Path', '5': 'Baronbell', '6': 'Mountain Path', 1: 'Zelbridge'} #Region number 1 no longer string
{'3': 'Cariva', '4': 'Old Path', '5': 'Baronbell', '6': 'Mountain Path', 1: 'Zelbridge', 2: 'Prairie Path'} #Region numbers 1 and 2 no longer string
{'4': 'Old Path', '5': 'Baronbell', '6': 'Mountain Path', 1: 'Zelbridge', 2: 'Prairie Path', 3: 'Cariva'} #ect
{'5': 'Baronbell', '6': 'Mountain Path', 1: 'Zelbridge', 2: 'Prairie Path', 3: 'Cariva', 4: 'Old Path'} #ect
{'6': 'Mountain Path', 1: 'Zelbridge', 2: 'Prairie Path', 3: 'Cariva', 4: 'Old Path', 5: 'Baronbell'} # Region numbers 1, 2, 3, 4, and 5 no longer string
{'6': 'Mountain Path', 1: 'Zelbridge', 2: 'Prairie Path', 3: 'Cariva', 5: 'Baronbell'}
Traceback (most recent call last):
File "C:/Users/crazy/PycharmProjects/rpg/main.py", line 581, in load
for key in worldmap["Regions"]:
RuntimeError: dictionary changed size during iteration
Process finished with exit code 1
I'm not exactly sure what's wrong with it but sadly I'll also have to do this for each location within a region. Any and all help is appreciated, as I've looked all over SO and google but to no avail.
with open(world_file) as infile:
worldmap = json.load(infile)
copy = worldmap.copy()
regions = worldmap["Regions"]
locations = copy.pop("Regions")
for key in worldmap["Regions"]:
value = worldmap["Regions"][key]
new_key = int(key)
worldmap["Regions"].update({new_key: value})
worldmap ["Regions"].pop(key)
print(str(worldmap["Regions"]) + "\n")```
Use For loop this way and update the key in loop itself:
mydict = {1: 'a', 2: 'b'}
for index, (key, value) in enumerate(mydict.items()):
print("index: {}, key: {}, value: {}".format(index, key, value))
mydict[index] = mydict.pop(key)
Or use can use List to force a copy of the keys to be made:
mydict = {1: 'a', 2: 'b'}
for index, key in enumerate(list(mydict)):
mydict[index] = mydict.pop(key)
# which will give output like:
# ---------------------------
# {0: 'a', 1: 'b'}

How can I convert an array inside a python dictionary to a tuple?

I have this dictionary:
{
0: array([-0.16638531, -0.11749843]),
1: array([-0.2318372 , 0.00917023]),
2: array([-0.42934129, -0.0675385 ]),
3: array([-0.63377579, -0.02102854]),
4: array([-0.26648222, -0.42038916]),
5: array([-0.17250316, -0.73490218]),
6: array([-0.42774336, -0.61259704]),
7: array([-0.55420825, -0.77304496]),
8: array([0.13900166, 0.07800885]),
9: array([0.42223986, 0.16563338]),
10: array([ 0.39895669, -0.09198566]),
12: array([0.24324618, 0.44829616]),
11: array([ 0.55394714, -0.17960723]),
13: array([0.192127 , 0.5988793]),
14: array([0.39554203, 0.7186038 ]),
15: array([0.53721604, 1. ])
}
I want to convert those numpy.ndarray values to tuples, and have something like this:
{
0: (-0.16638531, -0.11749843),
1: (-0.2318372 , 0.00917023),
...
}
From this answer here it looks like for each value in the dictionary you can:
tuple(arr)
So for the whole dictionary you can probably do something like:
new_dict = {key: tuple(arr) for key, arr in old_dict.items()}
Or easier to understand:
new_dict = {}
for key, arr in old_dict.items():
new_dict.update({key: tuple(arr)})
You can use a dictionary comprehension.
Python dictionaries have an .items() method that return a tuple of (key, value) for each key-value pair.
The comprehension recreates a new mapping with the original key and the array cast as a tuple.
from numpy import array
data = {
0: array([-0.16638531, -0.11749843]),
1: array([-0.2318372 , 0.00917023]),
2: array([-0.42934129, -0.0675385 ]),
3: array([-0.63377579, -0.02102854]),
4: array([-0.26648222, -0.42038916]),
5: array([-0.17250316, -0.73490218]),
6: array([-0.42774336, -0.61259704]),
7: array([-0.55420825, -0.77304496]),
8: array([0.13900166, 0.07800885]),
9: array([0.42223986, 0.16563338]),
10: array([ 0.39895669, -0.09198566]),
12: array([0.24324618, 0.44829616]),
11: array([ 0.55394714, -0.17960723]),
13: array([0.192127 , 0.5988793]),
14: array([0.39554203, 0.7186038 ]),
15: array([0.53721604, 1. ])
}
print({key: tuple(value) for key, value in data.items()})
OUTPUT:
{0: (-0.16638531, -0.11749843), 1: (-0.2318372, 0.00917023), 2: (-0.42934129, -0.0675385), 3: (-0.63377579, -0.02102854), 4: (-0.26648222, -0.42038916), 5: (-0.17250316, -0.73490218), 6: (-0.42774336, -0.61259704), 7: (-0.55420825, -0.77304496), 8: (0.13900166, 0.07800885), 9: (0.42223986, 0.16563338), 10: (0.39895669, -0.09198566), 12: (0.24324618, 0.44829616), 11: (0.55394714, -0.17960723), 13: (0.192127, 0.5988793), 14: (0.39554203, 0.7186038), 15: (0.53721604, 1.0)}
mapping = { key: (item[0], item[1]) for key, item in your_dict.items() }

How to create dictionary from another dictionary if some condition met

From dictionary :
{0: (u'Donald', u'PERSON'), 1: (u'John', u'PERSON'), 2: (u'Trump', u'PERSON'), 14: (u'Barack', u'PERSON'), 15: (u'Obama', u'PERSON'), 17: (u'Michelle', u'PERSON'), 18: (u'Obama', u'PERSON'), 30: (u'Donald', u'PERSON'), 31: (u'Jonh', u'PERSON'), 32: (u'Trump', u'PERSON')}
I'd like to create another dictionary as follows:
{u'Donald John Trump': 2, u'Barack Obama':1, u'Michele Obama':1}
Here 0,1,2 and 30,31,32 keys are increasing by 1 and occurred twice. And 14,15 17,18 occurred once each. Is there any way to create such dict?
I think the main problem you need to solve is to identify persons by grouping keys denoting an increasing int sequence, as you described it.
Fortunately, Python has a recipe for this.
from itertools import groupby
from operator import itemgetter
from collections import defaultdict
dct = {
0: ('Donald', 'PERSON'),
1: ('John', 'PERSON'),
2: ('Trump', 'PERSON'),
14: ('Barack', 'PERSON'),
15: ('Obama', 'PERSON'),
17: ('Michelle', 'PERSON'),
18: ('Obama', 'PERSON'),
30: ('Donald', 'PERSON'),
31: ('John', 'PERSON'),
32: ('Trump', 'PERSON')
}
persons = defaultdict(int) # Used for conveniance
keys = sorted(dct.keys()) # So groupby() can recognize sequences
for k, g in groupby(enumerate(keys), lambda d: d[0] - d[1]):
ids = map(itemgetter(1), g) # [0, 1, 2], [14, 15], etc.
person = ' '.join(dct[i][0] for i in ids) # "Donald John Trump", "Barack Obama", etc
persons[person] += 1
print(persons)
# defaultdict(<class 'int'>,
# {'Barack Obama': 1,
# 'Donald John Trump': 2,
# 'Michelle Obama': 1})
def add_name(d, consecutive_keys, result):
result_key = ' '.join(d[k][0] for k in consecutive_keys)
if result_key in result:
result[result_key] += 1
else:
result[result_key] = 1
d = {0: (u'Donald', u'PERSON'), 1: (u'John', u'PERSON'), 2: (u'Trump', u'PERSON'),
14: (u'Barack', u'PERSON'), 15: (u'Obama', u'PERSON'),
17: (u'Michelle', u'PERSON'), 18: (u'Obama', u'PERSON'),
30: (u'Donald', u'PERSON'), 31: (u'John', u'PERSON'), 32: (u'Trump', u'PERSON')}
sorted_keys = sorted(d.keys())
last_key = sorted_keys[0]
consecutive_keys = [last_key]
result = {}
for i in sorted_keys[1:]:
if i == last_key + 1:
consecutive_keys.append(i)
else:
add_name(d, consecutive_keys, result)
consecutive_keys = [i]
last_key = i
add_name(d, consecutive_keys, result)
print(result)
Output
{'Donald John Trump': 2, 'Barack Obama': 1, 'Michelle Obama': 1}

Search a key in a dict and assing the value of that key to a variable Python

i have this dict:
dict_meses = {1: 'Enero', 2: 'Febrero', 3: 'Marzo', 4: 'Abril', 5: 'Mayo', 6: 'Junio', 7: 'Julio', 8: 'Agosto',
9: 'Setiembre', 10: 'Octubre', 11: 'Noviembre', 12: 'Diciembre'}
I need to change the month on a string like this '14/1/2015' for the month that corresponds in the dict. For example if a have '14/1/2015' i need to change it to '1/Enero/2015'
I am trying to do something like this:
def xxx(days): -----> days is a list of tuples like this [('14/1/2015', 500), ...]
dict_months = {1: 'Enero', 2: 'Febrero', 3: 'Marzo', 4: 'Abril', 5: 'Mayo', 6: 'Junio', 7: 'Julio', 8: 'Agosto',
9: 'Setiembre', 10: 'Octubre', 11: 'Noviembre', 12: 'Diciembre'}
days_list = []
for i in days:
lista = list(i)
fecha_entera = lista[0].split('/') ---> ['14','1','2015']
dia = fecha_entera[1] ----------------> '1'
if int(dia) in dict_meses.keys():
fecha_entera[1] = ????------------> want to change '1' to 'Enero'
dias_lista.append(fecha_entera)
return dias_lista
Question: How can i take the value that corresponds to the key that the day represents?
If i am not explaining this to clear just let me know and i will try harder.
Thanks in advance for the help provided
For a string solution, use the string "replace" function on "/1/".
lista.replace("/" + dia + "/", "/" + dict_months[int(dia)] + "/")
You can use datetime to parse your dates using %B with srftime to get the output you want:
from datetime import datetime
dte = '14/1/2015'
print(datetime.strptime(dte,"%d/%m/%Y").strftime("%d/%B/%Y"))
%B will give you the locale’s full month name.
In [1]: from datetime import datetime
In [2]: dte = '14/1/2015'
In [3]: import locale
In [4]: locale.setlocale(locale.LC_ALL,"es_SV.utf_8")
Out[4]: 'es_SV.utf_8'
In [5]: print(datetime.strptime(dte,"%d/%m/%Y").strftime("%d/%B/%Y"))
14/enero/2015
If every first element is a date string:
def xxx(days):
return [datetime.strptime(dte, "%d/%m/%Y").strftime("%d/%B/%Y")
for dte, _ in days]
If you want to use your dict:
def xxx(days):
dict_months = {"1": 'Enero', "2": 'Febrero', "3": 'Marzo', "4": 'Abril', "5": 'Mayo', "6": 'Junio', "7": 'Julio',
"8": 'Agosto',
"9": 'Setiembre', "10": 'Octubre', "11": 'Noviembre', "12": 'Diciembre'}
days_list = []
for sub in map(list, days):
dy, mn, year = sub[0].split()
days_list.append("{}/{}/{}".format(dy, dict_months[mn], year))
return days_list
You should use the keys as strings, it is pointless having to cast to int to compare.

Why python dictonary gives me Keyerror?

I am reading excel file and creating dictionary using following code in file a.py.
productNo = int(worksheet.cell_value(curr_row, 1))
print "Product No :" + str(productNo)
products[productNo] = {}
while curr_cell < num_cells:
curr_cell += 1
header = str(worksheet.cell_value(0, curr_cell))
# Cell Types: 0=Empty, 1=Text, 2=Number, 3=Date, 4=Boolean, 5=Error, 6=Blank
cell_type = worksheet.cell_type(curr_row, curr_cell)
#print ' ',curr_cell,' <-> ', cell_type
cell_value = worksheet.cell_value(curr_row, curr_cell)
if cell_type == 0 or cell_type == 6:
products[productNo][header] = ""
if cell_type == 1:
#products[productNo] = {header :cell_value}
products[productNo][header] = cell_value
elif cell_type == 2:
cell_value = int(cell_value)
print "Header " + header
products[productNo][header] = cell_value
elif cell_type == 3:
products[productNo] = {header :cell_value}
elif cell_type == 4:
products[productNo] = {header :cell_value}
In file main.py I am calling above written code (in function) and catalouge.readExcel('D:/Personal/CatalogNo_1134.xls', products) by passing variable products as dictionary.
When dump it I am getting all keys and values.
print "Dump " + str(products)
print products.keys()
print products['28852']['ProductNo']
print products['28852']['Style']
Dump {28852: {'Category': u'Party Wear', 'Style': u'Designer', 'ProductNo': 28852, 'ProductGroup': u'Salwar Kameez', 'CatalogNo': 1134, 'ProductType': u'Salwar Kameez', 'SubCategoryDefinition': '', 'Fabric': u'Faux Georgette', 'MinWebPrice': 3395, 'Description': u'Capture The Exuberance Of Womanhood In Its Full Glory That Will Bring Out Your Fragility And Femininity. Genuine Magnificence Will Come Out Through The Dressing Style With This Off White Faux Georgette Salwar Kameez. The Appealing Lace|Resham Work Through The Attire Is Awe-Inspiring.', 'OptionOfSleeves': '', 'Rate/FreeSize': 2095, 'XLRate': 0, 'GenericName': u'Dress Material', 'SizeAvailable': u'Not Applicable', 'MaxLengthCholi': '', 'ItemTag': u'Enigmatic Off White Salwar Kameez', 'SubCategory': u'Other - Party Wear', 'Description of Blouse/Choli/Bottom': u'Paired With A Matching Bottom', 'Colour': u' Off White', 'Work': u'Lace|Resham', 'ExpressQty': 0, 'Occasion': u'Christmas,Diwali,Eid,Festival,Kitty Party,Mehendi,Navratri,Party Wear,Sangeet,Wedding', 'Weight': 1, 'Description of Dupatta': u'Comes With A Matching Dupatta', 'DeliveryDays': 8}, 28853: {...}}
keys are
[28852, 28853, 28854, 28855, 28856, 28857, 28858, 28859, 28860, 28861, 28862, 28863]
When I access it using products['28852']
Traceback (most recent call last):
print products['28852']['ProductNo']
KeyError: '28852'
You are accessing str 28852 while the key is integer. Please access with 28852.

Categories

Resources