I have this list of names: [Frank, Sam, Kevin, Jack]
Is it possible to create a dictionary using the names in the list to create something like this?
'Frank' : {'Sam': 0, 'Kevin': 0, 'Jack': 0},
'Sam' : {'Frank': 0, 'Kevin': 0, 'Jack': 0},
'Kevin' : {'Frank': 0, 'Sam': 0, 'Jack': 0}
'Jack' : {'Frank': 0, 'Sam': 0, 'Kevin': 0}
I want to know if it's possible to iterate through the list, pick the first name and then create a dictionary with it, with the other members in the list as keys and 0 as the default value. And then repeat it for the other elements in the list as well.
I was thinking of using something like this.
my_dynamic_vars = dict()
my_dynamic_vars.update({string: dict()})
Any help would be much appreciated.
You can use nested dictionary comprehensions:
>>> lst = ['Frank', 'Sam', 'Kevin', 'Jack']
>>> dct = {x:{y:0 for y in lst if y != x} for x in lst}
>>> dct
{'Frank': {'Kevin': 0, 'Sam': 0, 'Jack': 0}, 'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0}, 'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0}, 'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0}}
>>>
>>> # Just to demonstrate
>>> from pprint import pprint
>>> pprint(dct)
{'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0},
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0},
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0},
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0}}
>>>
ummm
d= {}
names = ["Frank","Sam","Kevin","Jack"]
for name in names:
d[name] = dict.fromkeys(set(names).difference([name]),0)
print d
is probably how I would do it ..
names = ['Frank', 'Sam', 'Kevin', 'Jack']
d = dict.fromkeys(names, 0)
names_dict = {}
for name in names:
temp = d.copy()
del temp[name]
names_dict.update([(name, temp)])
output:
>>> for d in names_dict:
>>> print d
'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0}
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0}
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0}
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0}
names = ['Frank', 'Sam', 'Kevin', 'Jack']
d = {name: dict.fromkeys([x for x in names if x != name], 0)
for name in names}
from pprint import pprint
pprint(d)
Output
{'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0},
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0},
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0},
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0}}
Related
I need to assign 0 and 1 as values to keys in the dictionaries:
combinations_string_list = [num_list_to_str(i) for i in itertools.product([0, 1], repeat=2)]
all_stategy = []
for i in range(16):
strategy_table = {x: y for x in combinations_string_list for y in [0, 1]}
all_stategy.append(strategy_table)
print(all_stategy)
I got [{'00': 1, '01': 1, '10': 1, '11': 1}, {'00': 1, '01': 1, '10': 1, '11': 1}, {'00': 1, '01': 1, '10': 1, '11': 1}, ...]
but I need [{'00': 0, '01': 0, '10': 0, '11': 0}, {'00': 0, '01': 0, '10': 0, '11': 1}, {'00': 0, '01': 0, '10': 1, '11': 0}, ...] instead.
How can I create this kind of value? Thanks!
You can zip the key sequence ["0", "1"] with each element of the cartesian product to produce input to dict:
>>> [dict(zip(["0", "1"], x)) for x in product([0,1], repeat=2)]
[{'0': 0, '1': 0}, {'0': 0, '1': 1}, {'0': 1, '1': 0}, {'0': 1, '1': 1}]
or
>>> values=[0,1]
>>> [dict(zip(map(str, values), x)) for x in product(values, repeat=2)]
I want to print possible substring in set of 3 and assign dictionary values if pattern matches with dictionary.keys() and store them into new dictionary
input:
dict1={'000': 0, '001': 0, '010': 0, '011': 0, '100': 1, '101': 0, '110': 1, '111': 0}
str1=['010110100']
output:
sub_string= [010,101,011...]
new dict= {'010':0, '101':0, '011':0, '110':1......}
try this:
[str1[0][i:i+3] for i in range(len(str1[0])-2) if str1[0][i:i+3] in dict1]
{str1[0][i:i+3] : dict1.get(str1[0][i:i+3]) for i in range(len(str1[0])-2) if str1[0][i:i+3] in dict1}
# ['010', '101', '011', '110', '101', '010', '100']
# {'010': 0, '101': 0, '011': 0, '110': 1, '100': 1}
You could do like this:
dict1={'000': 0, '001': 0, '010': 0, '011': 0, '100': 1, '101': 0, '110': 1, '111': 0}
str1= '010110100'
sub_string = []
d = {}
for i in range(len(str1)-2):
temp = str1[i:i+3]
sub_string.append(temp)
d[temp] = dict1.get(temp)
print(sub_string)
print(d)
['010', '101', '011', '110', '101', '010', '100']
{'010': 0, '101': 0, '011': 0, '110': 1, '100': 1}
Given the following code:
minimal example of list of lists:
c = [['dog', 'Sg', 'Good'], ['cat', 'Pl', 'Okay'], ['dog', 'Pl', 'Bad'],
['dog', 'Sg', 'Good'], ['cat', 'Pl', 'Okay'], ['dog', 'Pl', 'Okay'],
['dog', 'Sg', 'Good'], ['cat', 'Sg', 'Good'], ['dog', 'Pl', 'Bad'],
['dog', 'Sg', 'Good'], ['cat', 'Pl', 'Okay'], ['dog', 'Pl', 'Bad']]
create sets of words from c
outer_keys = set()
inner_keys = set()
for x in c:
outer_keys.add(x[0])
inner_keys |= set(x[1:])
create dict with for loop
Lemma = dict()
for i in outer_keys:
j_d = dict()
for j in inner_keys:
j_d[j] = 0
j_d[i] = 0 # this is the line I can't replicate with a comprehension
Lemma[i] = j_d
for loop result:
{'dog': {'Okay': 0, 'Pl': 0, 'Good': 0, 'Bad': 0, 'Sg': 0, 'dog': 0},
'cat': {'Okay': 0, 'Pl': 0, 'Good': 0, 'Bad': 0, 'Sg': 0, 'cat': 0}}
using dict comprehension:
This is where I need assistance. I haven't been able to replicate the for-loop with the dict comprehension
Lemma = {j: {i: 0 for i in inner_keys} for j in outer_keys}
Note: dog should be inside the value of outer dog and the same for cat
My dict comprehension result:
{'dog': {'Okay': 0, 'Pl': 0, 'Good': 0, 'Bad': 0, 'Sg': 0},
'cat': {'Okay': 0, 'Pl': 0, 'Good': 0, 'Bad': 0, 'Sg': 0}}
Question:
How can I replicate the result of the for-loop with the dict comprehension?
Order doesn't matter.
You can use dict.fromkeys together with inner_keys | {j}:
>>> {j: dict.fromkeys(inner_keys | {j}, 0) for j in outer_keys}
{'cat': {'Bad': 0, 'Good': 0, 'Okay': 0, 'Pl': 0, 'Sg': 0, 'cat': 0},
'dog': {'Bad': 0, 'Good': 0, 'Okay': 0, 'Pl': 0, 'Sg': 0, 'dog': 0}}
Just create a new dict from your inner dict
>>> {j: dict({i: 0 for i in inner_keys}, **{j:0}) for j in outer_keys}
{'dog': {'Bad': 0, 'Good': 0, 'Okay': 0, 'Sg': 0, 'dog': 0, 'Pl': 0}, 'cat': {'Bad': 0, 'Good': 0, 'Okay': 0, 'Sg': 0, 'Pl': 0, 'cat': 0}}
I got something like this:
> d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
> d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
> d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
I would like to sum values 'failed', passed and total into one dictionary
so the output should be like this:
d4 = {'System tests': {'failed': 6, 'passed': 1, 'total': 7},
'Func tests': {'failed': 9, 'passed': 2, 'total': 11}
What is the easiest solution to do such thing?
I can use basic libraries, except collections.
The solution must be generic, for example if some other dictionaries would appear in the future
input:
d1 = {'a': 100, 'b': 200, 'c':300}
d2 = {'a': 300, 'b': 200, 'd':400}
d = {k : d1.get(k, 0) + d2.get(k,0) for k in set(d1.keys()) | set(d2.keys())}
Output:
{'a': 400, 'b': 400, 'c': 300, 'd': 400}
Using Counter and defaultdict that is fairly straight forward like:
Code:
d4 = defaultdict(Counter)
for d in d1, d2, d3:
for k, subd in d.items():
d4[k].update(subd)
Test Code:
d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
from collections import Counter, defaultdict
d4 = defaultdict(Counter)
for d in d1, d2, d3:
for k, subd in d.items():
d4[k].update(subd)
print(d4)
Results:
defaultdict(<class 'collections.Counter'>, {
'System tests': Counter({'total': 7, 'failed': 6, 'passed': 1}),
'Func tests': Counter({'total': 11, 'failed': 9, 'passed': 2})
})
This will give you the output you are looking for, with no libraries.
d4 = {}
for d in d1, d2, d3:
for test, results in d.items():
if test not in d4:
d4[test] = {}
for key, value in results.items():
if key in d4[test]:
d4[test][key] += value
else:
d4[test][key] = value
Result:
{'System tests': {'failed': 6, 'passed': 1, 'total': 7}, 'Func tests': {'failed': 9, 'passed': 2, 'total': 11}}
If you cannot use collections.Counter, another solution is to use reduce
from functools import reduce # reduce was moved here in Python3
def add_dicts(dict_list):
def add(fst, snd):
return {k: fst[k] + snd[k] for k in fst}
return reduce(add, dict_list[1:], dict_list[0])
Using this in your code would look like this.
dict_list = [d1, d2, d3]
d4 = {}
for k in dict_list[0]:
d4[k] = add_dicts([d[k] for d in dict_list])
Although, this assumes all your dict are correctly formated.
You can use zip along with dict.items:
d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
def combine_dicts(*d):
return {a:{i:sum(h[i] for h in [b, c, d]) for i in ['failed', 'passed', 'total']} for [a, b], [_, c], [_, d] in zip(*d)}
print(combine_dicts(d1.items(), d2.items(), d3.items()))
Output:
{'System tests': {'failed': 6, 'total': 7, 'passed': 1}, 'Func tests': {'failed': 9, 'total': 11, 'passed': 2}}
I have this dictionary.
'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0}
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0}
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0}
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0}
I have the variables speaker and listener. A speaker is the name of the dictionary, and the listener can be one of the keys in the dictionary. For example 'Frank' is the speaker, and 'Jack','Sam' and 'Kevin' could either be a listener in the first dict created. I want to be able to increment the value for a specific listener. For example if speaker = 'Sam' and listener = 'Kevin', I want this to happen
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 1}
And vice versa
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 1}
Programming and python newbie here. Any help on how to do this would be greatly appreciated! I have been stuck on this for a while. Thanks.
Take a look at this:
d = {
'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0},
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0},
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0},
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0} }
d ['Frank'] ['Kevin'] += 1
print (d)
d['Frank'] is the listener dictionary of Frank, and d['Frank']['Kevin'] is how many times Kevin has listened to Frank. This value you can increment.
Or if the speaker-listener relation is symmetrical, you can try this:
def talk (speaker, listener, data):
data[speaker][listener] += 1
data[listener][speaker] += 1
d = {
'Frank': {'Jack': 0, 'Kevin': 0, 'Sam': 0},
'Sam': {'Frank': 0, 'Jack': 0, 'Kevin': 0},
'Kevin': {'Frank': 0, 'Jack': 0, 'Sam': 0},
'Jack': {'Frank': 0, 'Kevin': 0, 'Sam': 0} }
talk('Frank', 'Sam', d)
print(d)
I'd probably create a new Person object, to be honest.
class Person(object):
def __init__(self,name):
self.name = name
def speak(self,other):
for (speaker,listener) in ((self,other),(other,self)):
try: speaker.__dict__[listener.name] += 1
except KeyError: speaker.__dict__[listener.name] = 1
#property
def listeners(self):
return {name:value for name,value in self.__dict__.items() if name != "name"}
## DEMO
>>> Adam = Person("Adam")
>>> Steve = Person("Steve")
>>> Adam.speak(Steve)
>>> Adam.Steve
1
>>> Steve.Adam
1
>>> Paul = Person("Paul")
>>> for listener in [Adam,Steve]:
Paul.speak(listener)
>>> Paul.listeners
{"Adam":1, "Steve":1}
Another approach, mimicking #adsmith's answer, but avoiding tampering with __dict__ and thus making all possible person names permissible.
class Person:
directional = False
def __init__(self, name):
self.name = name
self.listeners = {}
def speak(self, other):
try: self.listeners[other] += 1
except KeyError: self.listeners[other] = 1
if Person.directional: return
try: other.listeners[self] += 1
except KeyError: other.listeners[self] = 1
def __getitem__(self, person):
try: return self.listeners[person]
except KeyError: return 0
def __repr__(self):
return self.name
Sample usage:
alice = Person('Alice')
bob = Person('Bob')
charles = Person('Charles')
alice.speak(bob)
alice.speak(bob)
bob.speak(charles)
print(alice[bob])
print(alice[charles])
print(alice[bob])
print(bob.listeners)