Matching/Counting lists in python dictionary - python

I have a dictionary {x: [a,b,c,d], y: [a,c,g,f,h],...}. So the key is one variable with the value being a list (of different sizes).
My goal is to match up each list against every list in the dictionary and come back with a count of how many times a certain list has been repeated.
I tried this but does not seem to work:
count_dict = {}
counter = 1
for value in dict.values():
count_dict[dict.key] = counter
counter += 1

You could map the lists to tuples so they can be used as keys and use a Counter dict to do the counting:
from collections import Counter
count = Counter(map(tuple, d.values()))

Related

Python: Count Values in multi-value Dictionary

How can I count the number of a specific values in a multi-value dictionary?
For example, if I have the keys A and B with different sets of numbers as values, I want get the count of each number amongst all of the dictionary's keys.
I've tried this code, but I get 0 instead of 2.
dic = {'A':{0,1,2},'B':{1,2}}
print(sum(value == 1 for value in dic.values()))
Counter is a good option for this, especially if you want more than a single result:
from collections import Counter
from itertools import chain
from collections import Counter
count = Counter(chain(*(dic.values())))
In the REPL:
>>> count
Counter({1: 2, 2: 2, 0: 1})
>>> count.get(1)
2
Counter simply tallies each item in a list. By using chain we treat a list of lists as simply one large list, gluing everything together. Feeding this right to Counter does the work of counting how many of each item there is.

Python: Trying to create n dictionaries with randomly selected values from a range

So i've tried:
import random as r
t = {'va1':r.randint(0,50),'va2':r.randint(0,15),'va3':r.randint(0,10)}
n=15
for _ in range(n):
new_dict = {k:t for k in range(n)}
print(new_dict)
That gave me a dictionary of random dictionaries from t, but they weren't unique, so just a dictionary full of one version of t.
What i'm looking for is a dictionary whose keys are 1,2,3...n and whose values are the dictionary t. But i need t to be different for each iteration of the loop.
Thanks for reading
Python doesn't re-run a dictionary literal just because you reference it. t is nothing more than that single dictionary you created at the start.
The solution is to create a new dictionary from scratch in the dictionary comprehension (both key and value expressions are executed anew for each iteration):
n=15
new_dict = {k: {'va1':r.randint(0,50),'va2':r.randint(0,15),'va3':r.randint(0,10)} for k in range(n)}
print(new_dict)
You may want to put creating the nested dictionary into a function:
def random_values_dict():
return {'va1':r.randint(0,50),'va2':r.randint(0,15),'va3':r.randint(0,10)}
new_dict = {k: random_values_dict() for k in range(n)}
Note that there is little point in creating a dictionary where the keys are consecutive numbers starting at 0. A list would be more space efficient and have the same performance characteristics mapping such numbers to values:
new_list = [random_values_dict() for k in range(n)]
new_list[0] and new_dict[0] both map to a generated dictionary in that case.

Count unique items in a list of dictionaries, python27

I have a list, and that list contains dictionaries. There may be duplicate dictionaries in the list.
I am trying to get a count of unique dictionaries in the list.
I have tried using collections.Counter, but i receive an error stating the items (dictionaries in my list) are not hashable.
Ultimately, I'd like to return a list containing only unique dictionaries, and each dictionary will contain a new key/value pair with -'cnt': .
Can someone help?
new_list = []
counts = []
for dict_ in your_list:
try:
i = new_list.index(dict_)
except ValueError:
counts.append(1)
new_list.append(dict_)
else:
counts[i] += 1
assert len(counts) == len(new_list)
for dict_, count in zip(new_list, counts):
dict_['cnt'] = count
del counts

Matching values in variable length lists containing sublists in python

I am trying to iterate through a dictionary where each key contains a list which in turn contains from 0 up to 20+ sub-lists. The goal is to iterate through the values of dictionary 1, check if they are in any of the sublists of dictionary 2 for the same key, and if so, add +1 to a counter and not consider that sublist again.
The code looks somewhat like this:
dict1={"key1":[[1,2],[6,7]],"key2":[[1,2,3,4,5,6,7,8,9]]}
dict2={"key1":[[0,1,2,3],[5,6,7,8],[11,13,15]],"key2":[[7,8,9,10,11],[16,17,18]]}
for (k,v), (k2,v2) in zip(dict1.iteritems(),dict2.iteritems()):
temp_hold=[]
span_overlap=0
for x in v:
if x in v2 and v2 not in temp_hold:
span_overlap+=1
temp_hold.append(v2)
else:
continue
print temp_hold, span_overlap
This does obviously not work mainly due to the code not being able to check hierarchally through the list and sublists, and partly due to likely incorrect iteration syntax. I have not the greatest of grasp of nested loops and iterations which makes this a pain. Another option would be to first join the sublists into a single list using:
v=[y for x in v for y in x]
Which would make it easy to check if one value is in another dictionary, but then I lose the ability to work specifically with the sublist which contained parts of the values iterated through, nor can I count that sublist only once.
The desired output is a count of 2 for key1, and 1 for key2, as well as being able to handle the matching sublists for further analysis.
Here is one solution. I am first converting the list of lists into a list of sets. If you have any control over the lists, make them sets.
def matching_sublists(dict1, dict2):
result = dict()
for k in dict1:
assert(k in dict2)
result[k] = 0
A = [set(l) for l in dict1[k]]
B = [set(l) for l in dict2[k]]
for sublistA in A:
result[k] += sum([1 for sublistB in B if not sublistA.isdisjoint(sublistB) ])
return result
if __name__=='__main__':
dict1={"key1":[[1,2],[6,7]],"key2":[[1,2,3,4,5,6,7,8,9]]}
dict2={"key1":[[0,1,2,3],[5,6,7,8],[11,13,15]],"key2":[[7,8,9,10,11],[16,17,18]]}
print(matching_sublists(dict1, dict2))

How to iterate through dict in random order in Python?

How can I iterate through all items of a dictionary in a random order? I mean something random.shuffle, but for a dictionary.
A dict is an unordered set of key-value pairs. When you iterate a dict, it is effectively random. But to explicitly randomize the sequence of key-value pairs, you need to work with a different object that is ordered, like a list. dict.items(), dict.keys(), and dict.values() each return lists, which can be shuffled.
items=d.items() # List of tuples
random.shuffle(items)
for key, value in items:
print key, value
keys=d.keys() # List of keys
random.shuffle(keys)
for key in keys:
print key, d[key]
Or, if you don't care about the keys:
values=d.values() # List of values
random.shuffle(values) # Shuffles in-place
for value in values:
print value
You can also "sort by random":
for key, value in sorted(d.items(), key=lambda x: random.random()):
print key, value
You can't. Get the list of keys with .keys(), shuffle them, then iterate through the list while indexing the original dict.
Or use .items(), and shuffle and iterate that.
import random
def main():
CORRECT = 0
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau',
'Arizona': 'Phoenix', 'Arkansas': 'Little Rock'} #etc... you get the idea of a dictionary
allstates = list(capitals.keys()) #creates a variable name and list of the dictionary items
random.shuffle(allstates) #shuffles the variable
for a in allstates: #searches the variable name for parameter
studentinput = input('What is the capital of '+a+'? ')
if studentinput.upper() == capitals[a].upper():
CORRECT += 1
main()
I wanted a quick way for stepping through a shuffled list, so I wrote a generator:
def shuffled(lis):
for index in random.sample(range(len(lis)), len(lis)):
yield lis[index]
Now I can step through my dictionary d like so:
for item in shuffled(list(d.values())):
print(item)
or if you want to skip creating a new function, here is a 2-liner:
for item in random.sample(list(d.values()), len(d)):
print(item)
As Charles Brunet have already said that the dictionary is random arrangement of key value pairs. But to make it really random you will be using random module.
I have written a function which will shuffle all the keys and so while you are iterating through it you will be iterating randomly. You can understand more clearly by seeing the code:
def shuffle(q):
"""
This function is for shuffling
the dictionary elements.
"""
selected_keys = []
i = 0
while i < len(q):
current_selection = random.choice(q.keys())
if current_selection not in selected_keys:
selected_keys.append(current_selection)
i = i+1
return selected_keys
Now when you call the function just pass the parameter(the name of the dictionary you want to shuffle) and you will get a list of keys which are shuffled. Finally you can create a loop for the length of the list and use name_of_dictionary[key] to get the value.

Categories