Extract x previous key-value pairs given a key from a dictionary - python

I have a dictionary like this:
dict_test ={1: 111, 2: 2222, 3:333, 4:4444, 5:5555, 6:6666,
7: 777, 8: 8888, 9:9999, 10:100010101}
and would like to create a subset of the dictionary, that takes the previous four values given the key 8 for instance. So the resulting expected dictionary would look like this:
dict_new ={4:4444, 5:5555, 6:6666, 7: 777, 8: 8888}
I tried to write a more general function below, where I can more generally determine how many previous values I should look back.
def get_x_prev_entries(dictionary: dict, key: str, prev: int):
if key in dictionary:
token = object()
keys = [token]*(prev*-1) + sorted(dictionary) + [token]*diff
print('keys' + str(keys))
new_dict = []
newkeys = []
new_prev= prev
# extract all keys that are between 0 and the specified difference
while new_prev is not 0:
new_prev -= 1
if len(newkeys) == 0:
newkeys= newkeys
else:
newkeys = newkeys.append(keys[keys.index(key)-new_diff])
print(newkeys)
print(new_diff)
new_dict = {k:v for k, v in dictionary.items() if k in newkeys}
return new_dict
else:
print('Key not found')
So to create my desired dictionary I would ideally enter
get_x_prev_entries(dict_test, 8, 4)
but at this moment I only get an empty dictionary returned. Any advice would be appreciated. Thanks!

Using an order dict
from collections import OrderedDict as od
dict_test ={1: 111, 2: 2222, 3:333, 4:4444, 5:5555, 6:6666, 7: 777, 8: 8888, 9:9999, 10:100010101}
od_dict = od(dict_test)
def get_previous_keys(od_dict, prev=4, given=8):
if given not in od_dict:
return
k, v = [], []
for i in range(given-prev, given):
k.append(i)
v.append(od_dict[i])
return dict(zip(k,v))
print(get_previous_keys(od_dict))
{4: 4444, 5: 5555, 6: 6666, 7: 777}

Related

how to remove dictionary element by outlier values Python

Suppose my dictionary contains > 100 elements and one or two elements have values different than other values; most values are the same (12 in the below example). How can I remove these a few elements?
Diction = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
I want a dictionary object:
Diction = {1:12,2:12,4:12,5:12,6:12,7:12}
It may be a bit slow because of the looping (especially as the size of the dictionary gets very large) and have to use numpy, but this will work
import numpy as np
Diction = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
dict_list = []
for x in Diction:
dict_list.append(Diction[x])
dict_array = np.array(dict_list)
unique, counts = np.unique(dict_array, return_counts=True)
most_common = unique[np.argmax(counts)]
new_Diction = {}
for x in Diction:
if Diction[x] == most_common:
new_Diction[x] = most_common
print(new_Diction)
Output
{1: 12, 2: 12, 4: 12, 5: 12, 6: 12, 7: 12}
d = {1:12,2:12,3:23,4:12,5:12,6:12,7:12,8:2}
new_d = {}
unique_values = []
unique_count = []
most_occurence = 0
# Find unique values
for k, v in d.items():
if v not in unique_values:
unique_values.append(v)
# Count their occurrences
def count(dict, unique_value):
count = 0
for k, v in d.items():
if v == unique_value:
count +=1
return count
for value in unique_values:
occurrences = count(d, value)
unique_count.append( (value, occurrences) )
# Find which value has most occurences
for occurrence in unique_count:
if occurrence[1] > most_occurence:
most_occurence = occurrence[0]
# Create new dict with keys of most occurred value
for k, v in d.items():
if v == most_occurence:
new_d[k] = v
print(new_d)
Nothing fancy, but direct to the point. There should be many ways to optimize this.
Output: {1: 12, 2: 12, 4: 12, 5: 12, 6: 12, 7: 12}

How to append one dict to dict and makes finally one

I have dictionary in python script like this
{key:value}
{key:value}
{key:value}
I wanted to make it into a single key dictionary like
[{'key':value} , {'key:value} , {'key':value}......]
My code is below:
for (recActorIMDBid, recActorName, recActorTopTen) in cursor:
recActorTopTen = str(recActorTopTen).replace(",", "_ ")
contentIDArray =[]
contentIDArray = recActorTopTen.split("_ ")
if len(contentIDArray) > 9:
stringOut = "ID," + str(recID) + ",IMDB ID," + str(recActorIMDBid) + ",NAME," + str(recActorName) + ",TOP TEN," \ + str(recActorTopTen)
print(stringOut)
I need to change the result to json, what should I Do?
This will work:
dict1 = {0: 5, 1: 8, 2: 3}
dict2 = {0: 6, 1: 2, 2: 4}
dict3 = {0: 7, 1: 9, 2: 2}
dicts = []
dicts.append(dict1)
dicts.append(dict2)
dicts.append(dict3)
Just iterate over items() (key-value pairs) and use a list comprehension
[{k: v} for k, v in my_dict.items()]
Note: I'm assuming your question has a few typos, because what you describe is not exactly valid.

For the common keys, how would you access the corresponding values

def query_RR(postings, qtext):
words = tokenize(qtext)
allpostings = [postings[w] for w in words]
for a in allpostings:
print a.keys()
And this was the result of the query
[0, 2, 3, 4, 6]
[1, 4, 5]
[0, 2, 4]
[4, 5]
The query is taking a user input term (qtext), tokenizing and generating a postings list for each token.
The posting list is a list of nested dictionaries.
e.g.
[{0 : 0.68426, 1: 0.26423}, {2: 0.6842332, 0: 0.9823}]
For the common keys, how would you access the corresponding values, for my example the common value is 0so how would you access values {0 : 0.68426, 0: 0.9823}?
Here is one way:
lst = [{0: 0.68426, 1: 0.26423}, {2: 0.6842332, 0: 0.9823}]
[d[0] for d in lst] # [0.68426, 0.9823]
Or if you need a dictionary:
{0: [d[0] for d in lst]} # {0: [0.68426, 0.9823]}
If you need to work out your common dictionary keys:
{i: [d[i] for d in lst] for i in set.intersection(*map(set, lst))}
# {0: [0.68426, 0.9823]}
Note that dictionary keys must be unique, so your required output is not possible.
lst = [{0 : 0.68426, 1: 0.26423}, {2: 0.6842332, 0: 0.9823}]
res = {}
for x in lst:
for key, value in x.items():
if key in res:
res[key].append(value)
else:
res[key] = [value]
This returns you a dictionary of the form {0: [0.68426, 0.9823]} because this {0 : 0.68426, 0: 0.9823} is not possible.

Function Return List as Dictionary?

My function below is taking a list of values and returning the counts of duplicates. I managed to make it count and print, but my task is to return it as a dictionary. I've been struggling to return in the correct format, any advice?
def counts(values):
d = {}
for val in values:
d.setdefault(val,0)
d[val] += 1
for val, count in d.items():
d = ("{} {}".format(val,count))
return d
counts([1,1,1,2,3,3,3,3,5]) # Should return → {1: 3, 2: 1, 3: 4, 5: 1}
Just return the created dictionary:
def counts(values):
d = {}
for val in values:
d.setdefault(val,0)
d[val] += 1
return d
Yields:
>>> counts([1,1,1,2,3,3,3,3,5])
{1: 3, 2: 1, 3: 4, 5: 1}
Of course, as Moses points out, a Counter is built for this so just use that instead:
from collections import Counter
def counts(values):
return dict(Counter(values))

Check for unique values in a dictionary and return a list

I've been struggling with this exercise for a couple of days now, each approximation I find, have a new problem, the idea is to find those unique values on a dictionary, and return a list with the keys
For example:
if aDictionary = {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0} then your the function should return [1, 3, 8], as the values 1,2 and 4 only appear once.
This is what I've tried so far:
def existsOnce(aDict):
counting = {}
tempList = []
for k in aDict.keys():
print k,
print aDict[k]
print 'values are:'
for v in aDict.values():
print v,
counting[v] = counting.get(v,0)+1
print counting[v]
tempNumbers = counting[v]
tempList.append(tempNumbers)
print tempList
If I go this way, I can point and delete those that are bigger than one, but the problem persists, I will have one zero, and I don't want it as was not unique in the original list.
def existsOnce2(aDict):
# import Counter module in the top with `from collections import Counter`
c = Counter()
for letter in 'here is a sample of english text':
c[letter] += 1
if c[letter] == 1:
print c[letter],':',letter
I tried to go this way with integers and check which ones appear from first time, but cannot translate it to dictionary or keep going from here. Also I'm not sure if importing modules are allowed in the answer and surely have to be a way to do it without external modules.
def existsOnce3(aDict):
vals = {}
for i in aDict.values():
for j in set(str(i)):
vals[j] = 1+ vals.get(j,0)
print vals
'''till here I get a counter of how many times a value appears in the original dictionary, now I should delete those bigger than 1'''
temp_vals = vals.copy()
for x in vals:
if vals[x] > 1:
print 'delete this: ', 'key:',x,'value:', vals[x]
temp_vals.pop(x)
else:
pass
print 'temporary dictionary values:', temp_vals
'''till here I reduced down the values that appear once, 1, 2 and 4, now I would need the go back and check the original dictionary and return the keys
Original dictionary: {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}
temp_vals {'1': 1, '2': 1, '4': 1}
keys on temp_vals (1,2,4) are the values associated to the keys I got to retrieve from original dictionary (1,3,8)
'''
print '---'
temp_list = []
for eachTempVal in temp_vals:
temp_list.append(eachTempVal)
print 'temporary list values:', temp_list
''' till here I got a temporary list with the values I need to search in aDict'''
print '---'
for eachListVal in temp_list:
print 'eachListVal:', eachListVal
for k,v in aDict.iteritems():
print 'key:',k,'value:',v
From here I cannot take the values for whatever reason and compare them, I've tried to extract the values with statements like:
if v == eachListVal:
do something
But I'm doing something wrong and cannot access to the values.
You just need to use your vals dict and keep keys from aDict with values that have a count == 1 in vals then calling sorted to get a sorted output list:
def existsOnce3(aDict):
vals = {}
# create dict to sum all value counts
for i in aDict.values():
vals.setdefault(i,0)
vals[i] += 1
# use each v/val from aDict as the key to vals
# keeping each k/key from aDict if the count is 1
return sorted(k for k, v in aDict.items() if vals[v] == 1)
Using a collections.Counter dict to do the counting just call Counter on your values then apply the same logic, just keep each k that has a v count == 1 from the Counter dict:
from collections import Counter
cn = Counter(aDict.values())
print(sorted(k for k,v in aDict.items() if cn[v] == 1))
How about this:
from collections import Counter
my_dict = {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}
val_counter = Counter(my_dict.itervalues())
my_list = [k for k, v in my_dict.iteritems() if val_counter[v] == 1]
print my_list
Result:
[1, 3, 8]
One liner:
>>> aDictionary = {1: 1, 3: 2, 6: 0, 7: 0, 8: 4, 10: 0}
>>> unique_values = [k for k,v in aDictionary.items() if list(aDictionary.values()).count(v)==1]
>>> unique_values
[1, 3, 8]

Categories