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))
Related
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}
I have a multiple dicts in the list. I want to count the number of occurances of the certain value from the list of dicts.
Here's the list of dict:
a = [{"a":"data1","b":"Nill","c":"data3","d":"Nill"},{"a":"dat1","b":"dat2","c":"dat3","d":"Nill"},{"a":"sa1","b":"sa2","c":"sa3","d":"Nill"}]
In here, i want to count the occurance of Nill in the Key. How to make it possible.
Here's the code i tried:
from collections import Counter
a = [{"a":"data1","b":"Nill","c":"data3","d":"Nill"},{"a":"dat1","b":"dat2","c":"dat3","d":"Nill"},{"a":"sa1","b":"sa2","c":"sa3","d":"Nill"}]
s = 0
for i in a:
d = (a[s])
#print(d)
q = 0
for z in d:
print(z)
z1=d[z]
#print(z)
if z1 == "Nill":
q = q+1
co = {z:q}
print(co)
Expected Output:
The count of Nill values in the list of dict
{a:0,b:1,c:0,d:3}
Try this :-
a = [{"a":"data1","b":"Nill","c":"data3","d":"Nill"},{"a":"dat1","b":"dat2","c":"dat3","d":"Nill"},{"a":"sa1","b":"sa2","c":"sa3","d":"Nill"}]
result_dict = {'a' : 0, 'b' : 0,'c' :0, 'd' : 0}
for i in a:
for key, value in i.items():
if value =="Nill":
result_dict[key] +=1
print(result_dict)
You can use the Counter directly by counting the boolean expression with something like this that takes advantage of the fact the the counter will count True as 1.
a = [{"a":"data1","b":"Nill","c":"data3","d":"Nill"},{"a":"dat1","b":"dat2","c":"dat3","d":"Nill"},{"a":"sa1","b":"sa2","c":"sa3","d":"Nill"}]
c = Counter()
for d in a:
c.update({k: v == 'Nill' for k, v in d.items()})
# c => Counter({'a': 0, 'b': 1, 'c': 0, 'd': 3})
EDIT:
To match the output required:
import pandas as pd
df = pd.DataFrame(a)
occ = {k: list(v.values()).count('Nill') for k,v in df.to_dict().items()}
Like this?
a = [{"a":"data1","b":"Nill","c":"data3","d":"Nill"},{"a":"dat1","b":"dat2","c":"dat3","d":"Nill"},{"a":"sa1","b":"sa2","c":"sa3","d":"Nill"}]
result = {}
for sub_list in a: # loop through the list
for key, val in sub_list.items(): # loop through the dictionary
result[key] = result.get(key, 0) # if key not in dictionary, add it
if val == 'Nill': # if finding 'Nill', increment that value
result[key] += 1
for key, val in result.items(): # show result
print(key, val)
Try this:
from collections import defaultdict
c = defaultdict(int, {i:0 for i in a[0].keys()})
for i in a:
for k,v in i.items():
if v=='Nill':
c[k] += 1
dict(c) will be your desired output.
{'a': 0, 'b': 1, 'c': 0, 'd': 3}
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}
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.
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]