Dictionary is not being added to - python-3.x

I'm trying to create a dictionary using keys and values from other dictionaries. The issue I'm having is that the dictionary I want to return comes up empty.
Note:
USER_RATING_DICT_SMALL = {1: {68735: 3.5, 302156: 4.0}, 2: {68735: 1.0, 124057: 1.5, 293660: 4.5}}
MOVIE_USER_DICT_SMALL = {293660: [2], 68735: [1, 2], 302156: [1], 124057: [2]}
def movies_to_users(user_ratings):
"""Return a dictionary of movie ids to list of users who rated the movie,
using information from the user_ratings dictionary of users to movie
ratings dictionaries.
>>> result = movies_to_users(USER_RATING_DICT_SMALL)
>>> result == MOVIE_USER_DICT_SMALL
True
"""
user_list = []
movie_to_users = {}
for items in user_ratings.items():
user_id = items[0]
user_list.append(user_id)
for items in user_ratings.items():
movie_id = items[1]
if movie_id in user_list:
movie_to_users[movie_id] = [user_list]
return movie_to_users
I created an empty dictionary for all the values and keys to accumulate to but it is not accumulating; it returns an empty dictionary instead. I want the output to be == MOVIE_USER_DICT_SMALL

A pretty short solution might be
MOVIE_USER_DICT_SMALL = {}
for user, data in USER_RATING_DICT_SMALL.items():
for movie in data.keys():
if not movie in MOVIE_USER_DICT_SMALL.keys():
# add entry for each movie
# will be an empty list if no user rated.
MOVIE_USER_DICT_SMALL[movie] = []
# for user in current iteration, there MUST be a rating...
# otherwise, movie would not be in data.keys()
MOVIE_USER_DICT_SMALL[movie] += [user]
MOVIE_USER_DICT_SMALL
# {68735: [1, 2], 302156: [1], 124057: [2], 293660: [2]}
The trick is to use key and value as returned by dict.items()

Related

Python nested dictionary Issue when iterating

I have 5 list of words, which basically act as values in a dictionary where the keys are the IDs of the documents.
For each document, I would like to apply some calculations and display the values and results of the calculation in a nested dictionary.
So far so good, I managed to do everything but I am failing in the easiest part.
When showing the resulting nested dictionary, it seems it's only iterating over the last element of each of the 5 lists, and therefore not showing all the elements...
Could anybody explain me where I am failing??
This is the original dictionary data_docs:
{'doc01': ['simpl', 'hello', 'world', 'test', 'python', 'code'],
'doc02': ['today', 'wonder', 'day'],
'doc03': ['studi', 'pac', 'today'],
'doc04': ['write', 'need', 'cup', 'coffe'],
'doc05': ['finish', 'pac', 'use', 'python']}
This is the result I am getting (missing 'simpl','hello', 'world', 'test', 'python' in doc01 as example):
{'doc01': {'code': 0.6989700043360189},
'doc02': {'day': 0.6989700043360189},
'doc03': {'today': 0.3979400086720376},
'doc04': {'coffe': 0.6989700043360189},
'doc05': {'python': 0.3979400086720376}}
And this is the code:
def tfidf (data, idf_score): #function, 2 dictionaries as parameters
tfidf = {} #dict for output
for word, val in data.items(): #for each word and value in data_docs(first dict)
for v in val: #for each value in each list
a = val.count(v) #count the number of times that appears in that list
scores = {v :a * idf_score[v]} # dictionary that will act as value in the nested
tfidf[word] = scores #final dictionary, the key is doc01,doc02... and the value the above dict
return tfidf
tfidf(data_docs, idf_score)
Thanks,
Did you mean to do this?
def tfidf(data, idf_score): # function, 2 dictionaries as parameters
tfidf = {} # dict for output
for word, val in data.items(): # for each word and value in data_docs(first dict)
scores = {} # <---- a new dict for each outer iteration
for v in val: # for each value in each list
a = val.count(v) # count the number of times that appears in that list
scores[v] = a * idf_score[v] # <---- keep adding items to the dictionary
tfidf[word] = scores # final dictionary, the key is doc01,doc02... and the value the above dict
return tfidf
... see my changes with <----- arrow :)
Returns:
{'doc01': {'simpl': 1,
'hello': 1,
'world': 1,
'test': 1,
'python': 1,
'code': 1},
'doc02': {'today': 1, 'wonder': 1, 'day': 1},
'doc03': {'studi': 1, 'pac': 1, 'today': 1},
'doc04': {'write': 1, 'need': 1, 'cup': 1, 'coffe': 1},
'doc05': {'finish': 1, 'pac': 1, 'use': 1, 'python': 1}}

How to Merge Two Dictionaries or Arrays in GDScript (Godot Engine)?

Say I have two Dictionaries (or could be Arrays), each having sub-dictionaries (or sub-arrays):
var dict_A = {'a': 1, 'sub_dict': {'hello': 'world', 'quick': 'fox'}}
var dict_B = {'b': 2, 'sub_dict': {'hello': 'godot'}}
Is there a builtin method in GDScript to merge them, including the sub-dictionaries or sub-arrays?
Expected result would be:
merge_dict(dict_A, dict_B)
# {'a': 1, 'b': 2, 'sub_dict': {'hello': 'godot', 'quick': 'fox'}}
There's no builtin method in GDScript for that, but you can use the following functions (find usage examples, unit tests, and more on this Github gist):
Observation: when using deep_merge=true with merge_array, all sub-dictionaries and sub-arrays must be JSON serializable.
func merge_array(array_1: Array, array_2: Array, deep_merge: bool = false) -> Array:
var new_array = array_1.duplicate(true)
var compare_array = new_array
var item_exists
if deep_merge:
compare_array = []
for item in new_array:
if item is Dictionary or item is Array:
compare_array.append(JSON.print(item))
else:
compare_array.append(item)
for item in array_2:
item_exists = item
if item is Dictionary or item is Array:
item = item.duplicate(true)
if deep_merge:
item_exists = JSON.print(item)
if not item_exists in compare_array:
new_array.append(item)
return new_array
func merge_dict(dict_1: Dictionary, dict_2: Dictionary, deep_merge: bool = false) -> Dictionary:
var new_dict = dict_1.duplicate(true)
for key in dict_2:
if key in new_dict:
if deep_merge and dict_1[key] is Dictionary and dict_2[key] is Dictionary:
new_dict[key] = merge_dict(dict_1[key], dict_2[key])
elif deep_merge and dict_1[key] is Array and dict_2[key] is Array:
new_dict[key] = merge_array(dict_1[key], dict_2[key])
else:
new_dict[key] = dict_2[key]
else:
new_dict[key] = dict_2[key]
return new_dict
This code is licensed under BSD 3-Clause License | Copyright 2022 Hackverse.org

Python: Convert 2d list to dictionary with indexes as values

I have a 2d list with arbitrary strings like this:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
I want to create a dictionary out of this:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
How do I do this? This answer answers for 1D list for non-repeated values, but, I have a 2d list and values can repeat. Is there a generic way of doing this?
Maybe you could use two for-loops:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
d = {}
overall_idx = 0
for sub_lst in lst:
for word in sub_lst:
if word not in d:
d[word] = overall_idx
# Increment overall_idx below if you want to only increment if word is not previously seen
# overall_idx += 1
overall_idx += 1
print(d)
Output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
You could first convert the list of lists to a list using a 'double' list comprehension.
Next, get rid of all the duplicates using a dictionary comprehension, we could use set for that but would lose the order.
Finally use another dictionary comprehension to get the desired result.
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
# flatten list of lists to a list
flat_list = [item for sublist in lst for item in sublist]
# remove duplicates
ordered_set = {x:0 for x in flat_list}.keys()
# create required output
the_dictionary = {v:i for i, v in enumerate(ordered_set)}
print(the_dictionary)
""" OUTPUT
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
"""
also, with collections and itertools:
import itertools
from collections import OrderedDict
lstdict={}
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
lstkeys = list(OrderedDict(zip(itertools.chain(*lst), itertools.repeat(None))))
lstdict = {lstkeys[i]: i for i in range(0, len(lstkeys))}
lstdict
output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}

AttributeError: 'tuple' object has no attribute 'get' in Python 3

I have two lists. one of candidates and one of votes received. I want to sort them descending by votes received. Zipping works fine. When I print the type of the resultant list it comes back as class 'list'. Next I sort and, bam!, get an AttributeError: 'tuple' object has no attribute get. I don't know how to fix this and would appreciate guidance.
for i in range(len(uniquecandidate)):
result = zip(uniquecandidate, votes) # zips two lists together
result_list = list(result)
print(type(result_list)) # returns <class 'list'>
result_list.sort(key=lambda x: x.get('votes'), reverse=True) #sort by vote number
print(result_list, end='\n\n')
zip returns a list of tuples; you can sort them by accessing the elements with their index:
result_list.sort(key=lambda x: x[1], reverse=True)
if you like to be more explicit, you can use collections.namedtuple, and access the element via dot notation on the attribute name:
from collections import namedtuple
Poll = namedtuple('Poll', ['candidate', 'numvotes'])
uniquecandidate = ['a', 'b', 'c', 'd']
votes = [3, 4, 7, 1]
poll_results = list(map(Poll, uniquecandidate, votes))
poll_results.sort(key=lambda x: x.numvotes, reverse=True)
print(poll_results)
or with typing.NamedTuple:
from typing import NamedTuple
class Poll(NamedTuple):
candidate: str
numvotes: int
uniquecandidate = ['a', 'b', 'c', 'd']
votes = [3, 4, 7, 1]
poll_results = list(map(Poll, uniquecandidate, votes))
poll_results.sort(key=lambda x: x.numvotes, reverse=True)
print(poll_results)
out:
[Poll(candidate='c', numvotes=7), Poll(candidate='b', numvotes=4), Poll(candidate='a', numvotes=3), Poll(candidate='d', numvotes=1)]
Because your candidates and votes are stored in a tuple objects, the get() method won't work on them like it would on a dictionary. I recommend switching from
x.get('votes')
to this:
x[1]
This will get index 1 of each tuple (which in your case is the vote count).

dictionary with nested list values to single list of values

I am trying to make single list of values in dictionary for each key. Bellow is problem. I am trying to parse list in Jinja and looks better to convert them into one before taking to template.
Problem:
{'EFTPOS': [[10.0, 5.0], 15.0], 'StoreDeposit': [[5.0, 6.0], 11.0]}
Result:
{'EFTPOS': [10.0, 5.0, 15.0], 'StoreDeposit': [5.0, 6.0, 11.0]}
Please try this code snippet.I have defined a method to remove the nested list and convert it into a flat list.
output = []
def rmNest(ls):
for i in ls:
if type(i) == list:
rmNest(i)
else:
output.append(i)
return output
a_dict = {'EFTPOS': [[10.0, 5.0], 15.0], 'StoreDeposit': [[5.0, 6.0], 11.0]}
new_dict = {}
for i in a_dict:
new_dict[i] = rmNest(a_dict[i])
output = []

Resources