How to sort the keys of a dictionary alpabetically - python

I want to take a dictionary, where the key is a string and the value a list of strings, and be able to print it in a new file where the keys are alphabetized, as well as the values. I'm not having any issue with the values. The problem lies in figuring out how to get the keys to print in the file alphabetically. Here is what I have:
def write_movie_info(string, aDict):
newFile = open(string, 'w')
myList = []
for movie in aDict:
aDict[movie].sort()
myList.append([movie] + aDict[movie])
for aList in myList:
joiner = ", ".join(aList[1:])
newFile.write(aList[0] + ': ' + joiner + '\n')
and the dictionary is:
movies = {"Chocolat": ["Juliette Binoche", "Judi Dench", "Johnny Depp", "Alfred Molina"], "Skyfall": ["Judi Dench", "Daniel Craig", "Javier Bardem", "Naomie Harris"]}
write_movie_info("Test.txt", movies)

Rather than iterating over the dictionary, you can iterate over its sorted keys created with:
sorted(aDict.keys())
Here's the function modified to just print the list:
def write_movie_info(string, aDict):
myList = []
sorted_keys = sorted(aDict.keys())
for movie in sorted_keys:
aDict[movie].sort()
myList.append([movie] + aDict[movie])
print(myList)
movies = {"Lawrence of Arabia": ["Peter O'Toole", "Omar Sharif"], "Chocolat": ["Juliette Binoche", "Judi Dench", "Johnny Depp", "Alfred Molina"], "Skyfall": ["Judi Dench", "Daniel Craig", "Javier Bardem", "Naomie Harris"]}
write_movie_info("Test.txt", movies)
Prints:
[['Chocolat', 'Alfred Molina', 'Johnny Depp', 'Judi Dench', 'Juliette Binoche'], ['Lawrence of Arabia', 'Omar Harif', "Peter O'Toole"], ['Skyfall', 'Daniel Craig', 'Javier Bardem', 'Judi Dench', 'Naomie Harris']]

You can use sorted method to sort your dictionary using key
sorted(your_dict.items(), key=lambda x: x[0])
and you can directly iterate it.
for key, value in sorted(your_dict.items(), key=lambda x: x[0]):
# do something
ref: https://docs.python.org/3/library/functions.html#sorted

OrderedDict() could be used to maintain the insertion-ordering, once the keys are sorted.
Ex.
import collections
movies = {"Skyfall": ["Judi Dench", "Daniel Craig", "Javier Bardem", "Naomie Harris"],
"Chocolat": ["Juliette Binoche", "Judi Dench", "Johnny Depp", "Alfred Molina"]}
order_dict = collections.OrderedDict(sorted(movies.items(), key=lambda x: x[0]))
print(order_dict)
O/P:
OrderedDict([('Chocolat', ['Juliette Binoche', 'Judi Dench', 'Johnny Depp', 'Alfred Molina']), ('Skyfall', ['Judi Dench', 'Daniel Craig', 'Javier Bardem', 'Naomie Harris'])])

Related

Nested loops in Python with two list

Why my loop not return first values? I want replaces specific text if this text exist in my value, but if not exist, i want get a initial meaning. In last value I get that i need, but first value my code miss.
p = ["Adams","Tonny","Darjus FC", "Marcus FC", "Jessie AFC", "John CF", "Miler
SV","Redgard"]
o = [' FC'," CF"," SSV"," SV"," CM", " AFC"]
for i, j in itertools.product(p, o):
if j in i:
name = i.replace(f"{j}","")
print(name)
elif j not in i:
pass
print(i)
I got this:
Darjus
Marcus
Jessie
John
Miler
Redgard
but i want this:
Adams
Tonny
Darjus
Marcus
Jessie
John
Miler
Redgard
The use of product() is going to make solving this problem a lot harder than it needs to be. It would be easier to use a nested loop.
p = ["Adams", "Tonny", "Darjus FC", "Marcus FC",
"Jessie AFC", "John CF", "Miler SV", "Redgard"]
o = [' FC', " CF", " SSV", " SV", " CM", " AFC"]
for i in p:
# Store name, for if no match found
name = i
for j in o:
if j in i:
# Reformat name if match
name = i.replace(j, "")
print(name)
If you would like to store the names in a list, here's one way to do it:
p = ['Adams', 'Tonny', 'Darjus FC', 'Marcus FC', 'Jessie AFC', 'John CF', 'Miler SV', 'Redgard']
o = ['FC', 'CF', 'SSV', 'SV', 'CM', 'AFC']
result = []
for name in p:
if name.split()[-1] in o:
result.append(name.split()[0])
else:
result.append(name)
print(result)
['Adams', 'Tonny', 'Darjus', 'Marcus', 'Jessie', 'John', 'Miler', 'Redgard']

How to print the character that has been found on my string?

I have a string where I want to search if some words are in it. (Multiple words)
How can I print the word that got found in the string?
Here is my code:
MLB_team = {
'Colorado' : 'Rockies',
'Boston' : 'Red Sox',
'Minnesota': 'Twins',
'Milwaukee': 'France',
'Seattle' : 'Mariners'
}
def location():
mlb_str = str(MLB_team)
location = ["Cuba", "France", "USA"]
if any(x in mlb_str for x in location):
print("yes")
else:
print("no")
location()
For now it print "yes" because the word "France" is on the Mlb _team string. But I would also like to print the word that has been found in the string ("France")
You'd want to use a loop to get access to the exact element that is found.
for x in location:
if x in str(MLB_team):
print(x)
continue # if you only want the first
However, rather than using a string of the entire dictionary, I suggest looping over its keys and values individually
for k, v in MLB_team.items():
for x in location:
if x in str(k):
print(k, x)
if x in str(v):
print(v, x)
you can do it like this:
MLB_team = {
'Colorado' : 'Rockies',
'Boston' : 'Red Sox',
'Minnesota': 'Twins',
'Milwaukee': 'France',
'Seattle' : 'Mariners'
}
def location():
mlb_str = str(MLB_team)
location = ["Cuba", "France", "USA"]
flag = False
for x in location:
if x in mlb_str:
print(x)
flag = True
if flag:
print("yes")
else:
print("no")
location()
def location():
location = ["Cuba", "France", "USA"]
#1. get the dict keys and store in list
mlbkey_list = []
for x in MLB_team.keys():
mlbkey_list.append(x)
#2. repeat same for values
mlbvalues_list = []
for x in MLB_team.values():
mlbvalues_list.append(x)
#3. merge both lists
mainlist = mlbkey_list + mlbvalues_list
#4. compare 2 lists
for x in location:
for y in mainlist:
if x == y:
print(f"Yes: {x}")
else:
print("No")
location()
You can have a set intersection like this
def location():
location = ["Cuba", "France", "USA"]
my_set = {*MLB_team.keys(), *MLB_team.values()}
print(my_set.intersection(set(location)))
location()

Easy way to map values from list of list to dictionary

Inputs
I have two lists of lists.
rule_seq =
[['#1', '#2', '#3'],
['#1', '#2', '#3']]
KG_seq =
[['nationality', 'placeOfBirth', 'locatedIn'],
['nationality', 'hasFather', 'nationality']]
I have to map the values in the same index to the dictionary with the value of rule_seq as the key in the list of above.
My desired output is
Output
unify_dict =
{'#1': ['nationality'],
'#2': ['placeOfBirth', 'hasFather'],
'#3': ['locatedIn', 'nationality']}
I made a dictionary as follows by flattening and zipping both lists of lists to check whether keys and values are in the dictionary.
My code is as follows.
def create_unify_dict(rule_seq, KG_seq):
unify_dict = collections.defaultdict(list)
flat_aug_rule_list = list(itertools.chain.from_iterable(rule_seq))
flat_aug_KG_list = list(itertools.chain.from_iterable(KG_seq))
[unify_dict[key].append(val) for key, val in zip(flat_aug_rule_list, flat_aug_KG_list)
if key not in unify_dict.keys() or val not in unify_dict[key]]
return unify_dict
unify_dict = create_unify_dict(rule_seq, KG_seq)
Is there a simpler way to get the result I want?
You can just call append using the same defualtdict with second level of nesting.
from collections import defaultdict
result = defaultdict(list)
for keyList,valueList in zip(rule_seq, KG_seq):
for key,item in zip(keyList, valueList):
if item not in result[key]: result[key].append(item)
OUTPUT:
defaultdict(<class 'list'>,
{'#1': ['nationality'],
'#2': ['placeOfBirth', 'hasFather'],
'#3': ['locatedIn', 'nationality']})
You can use collections:
import collections
# Create a defaultdict with list as value type
result = collections.defaultdict(list)
for s0, s1 in zip(rule_seq, KG_seq):
for v0, v1 in zip(s0, s1):
if v1 not in result[v0]:
result[v0].append(v1)
print({k: v for k, v in result.items()})
# {
# '#1': ['nationality'],
# '#2': ['placeOfBirth', 'hasFather'],
# '#3': ['locatedIn', 'nationality'],
# }
This would be my homemade approach using no modules. Vanilla Python.
combine = [list(set(l)) for l in [[lst[i] for lst in KG_seq] for i in range(len(KG_seq[0]))]]
dct = {place:st for place,st in zip(rule_seq[0],combine)}
output
{'#1': ['nationality'], '#2': ['hasFather', 'placeOfBirth'], '#3': ['nationality', 'locatedIn']}
oversimplified version
combine = []
for i in range(len(KG_seq[0])):
group = []
for lst in KG_seq:
group.append(lst[i])
combine.append(group)
newComb = []
for simp in combine:
newComb.append(list(set(simp)))
dct = {}
for place,st in zip(rule_seq[0],combine):
dct[place] = st
print(dct)
undersimplified
dct = {place:st for place,st in zip(rule_seq[0],[list(set(l)) for l in [[lst[i] for lst in KG_seq] for i in range(len(KG_seq[0]))]])}
Based on the following assumptions there could be several forms to what your method look like
rule_seq and kg_seq are equal in length
rule_seq and kg_seq items are also equal in length
One liner
def one_liner(rule_seq, kg_seq):
ret = {}
[ret.update({idx: ret.get(idx, set()) | {val}}) for arr_idx, arr_val in zip(rule_seq, kg_seq) for idx, val in zip(arr_idx, arr_val)]
return ret
Single loop + one liner
def one_loop(rule_seq, kg_seq):
ret = {}
for arr_idx, arr_val in zip(rule_seq, kg_seq):
[ret.update({idx: ret.get(idx, set()) | {val}}) for idx, val in zip(arr_idx, arr_val)]
return ret
Nested loops
def nested_loop(rule_seq, kg_seq):
ret = {}
for arr_idx, arr_val in zip(rule_seq, kg_seq):
for idx, val in zip(arr_idx, arr_val):
ret[idx] = ret.get(idx, set()) | {val}
return ret
Testing these out
one_liner(rule_seq, KG_seq)
{'#1': {'nationality'},
'#2': {'hasFather', 'placeOfBirth'},
'#3': {'locatedIn', 'nationality'}}
one_loop(rule_seq, KG_seq)
{'#1': {'nationality'},
'#2': {'hasFather', 'placeOfBirth'},
'#3': {'locatedIn', 'nationality'}}
nested_loop(rule_seq, KG_seq)
{'#1': {'nationality'},
'#2': {'hasFather', 'placeOfBirth'},
'#3': {'locatedIn', 'nationality'}}
d = {}
for i in range(len(rule_seq)):
for j in range(len(rule_seq[i])):
rule, kg = rule_seq[i][j], KG_seq[i][j]
if (rule not in d.keys()):
d[rule] = [kg]
elif kg not in d[rule]:
d[rule].append(kg)
result:
{'#1': ['nationality'], '#2': ['placeOfBirth', 'hasFather'], '#3': ['locatedIn', 'nationality']}

zip Cuts off After First Letter

I'm trying to run the following code:
def by_primary_key(table, key, fields) -> object:
key_columns = get_key_columns(table, key )
print("key columns in get by primary key " , key_columns)
print("key, " , key )
zip_it = list(zip(key_columns, key))
print("zip_it", zip_it )
dictt = dict(zip_it)
print("dict", dictt)
The output I want for zip_it is: [('playerID', 'willite01')]
but the output the program produces is:
key columns in get by primary key ['playerID']
key, willite01
zip_it [('playerID', 'w')]
dict {'playerID': 'w'}
Where am I going wrong?
The following worked
key_columns = get_key_columns(table, key )
lst = []
lst.append(key)
tmp = dict(zip(key_columns, lst))
result = find_by_template1(table, tmp, fields)
return result

How can I sort a list of dicts arbitrarily by a particular key?

How can I sort my list of dicts by their name values according to an arbitrary ordering? I want dicts with a name of 720p to come first, then dicts with a name of 1080p, and finally dicts with a name of 360p.
hosters = []
for entry in json.loads(aResult[1][0]):
if 'file' not in entry or 'label' not in entry: continue
sLabel = sName + ' - ' + entry['label'].encode('utf-8')
hoster = dict()
hoster['link'] = entry['file']
hoster['name'] = sLabel
hoster['resolveable'] = True
hosters.append(hoster)
You're going to need to use a custom sorting function. Something like this should work:
def sort_by_resolution(hoster):
desired_order = ['720p', '1080p', '360p']
if hoster['name'] in desired_order:
return desired_order.index(hoster['name'])
else:
return len(desired_order)
sorted(foo, key=sort_by_resolution)
# [{'name': '720p'}, {'name': '1080p'}, {'name': '360p'}]

Categories

Resources