I need help using Dictionary of dictionary python - python

I am trying to collect items in a dictionary:
enter code here
key1:
[
('text1', ['a', 'b', 'c']),
('text2', ['f', 'g']),
('text3',['h','i'])
]
#I tried to use collections.defaultdict() as
mydict = collections.defaultdict(list)
temp = collections.defaultdict(list)
temp["text1"].append(['a', 'b', 'c'])
temp["text2"].append(['f', 'g'])
temp["text3"].append(['h','i'])
mydict[key] = temp
I am confused and I am new to python. Above structure doesn't need to be a list I just wanted to hold these multiple things with key1, there would be multiple keys like key1.
Please advice me the best way I can do it, Also I want to sort this dictionary based on the top level keys (key1, key2 etc).

temp = {}
mydict = {}
temp["text1"] = ['a', 'b', 'c']
temp["text2"] = ['f', 'g']
temp["text3"] = ['h','i']
mydict['key1'] = list(temp.items())
mydict
the output is:
{'key1': [('text1', ['a', 'b', 'c']),
('text2', ['f', 'g']),
('text3', ['h', 'i'])]}

Related

How to check if a name is in a dictionary when the values are lists of names

I have a list of names, and I am trying to loop through that list and see if a name is a value in the name_types dictionary, and if it is then I want to add the name to a results list with a list of the name types that it belongs to, however, I am not sure about how to do this. Also, I want to store None if it is not a part of any.
name_types = {'Protocol': ['a', 'b', 'c'], 'Tech': ['a', 'b', 'd']}
names = ['a', 'b', 'c', 'd']
# Goal
result[['a', ['Protocol', 'Tech']], ['b', ['Protocol', 'Tech']], ['c', ['None']], ['d', ['Tech']]]
I tried something like this, but I got too many values to unpack error:
result = []
for n in names:
list_types = []
for key, list_names in name_types:
if d in list_names:
list_types.append(key)
result.append(d, list_types)
print(result)
Your data and result don't match ('c' is a 'Protocol'). I've removed 'c' to match the desired result:
name_types = {'Protocol': ['a', 'b'], 'Tech': ['a', 'b', 'd']}
names = ['a', 'b', 'c', 'd']
result = []
for name in names:
current = [name,[]]
for k,v in name_types.items():
if name in v:
current[1].append(k)
if not current[1]:
current[1].append('None')
result.append(current)
print(result)
Output:
[['a', ['Protocol', 'Tech']], ['b', ['Protocol', 'Tech']], ['c', ['None']], ['d', ['Tech']]]
Iterate over a dict key+value with .items(), then fix the variable d => n
for n in names:
list_types = []
for key, list_names in name_types.items():
if n in list_names:
list_types.append(key)
result.append([n, list_types])
[['a', ['Protocol', 'Tech']], ['b', ['Protocol', 'Tech']], ['c', ['Protocol']], ['d', ['Tech']]]
Could do it another way, maybe nicer
result = {name: [] for name in names}
for key, list_names in name_types.items():
for name in list_names:
result[name].append(key)
print(result.items())

Why are the keys of a dictionary going inside the items?

I have a problem that it seems to me that it doesn't make sense. I am defining a dictionary and using it to generate a list, with keys as the first elements of the list. But when I run it, not only the list is created, but the dictionary is modified. I need to know why this is happening and in which other way I could do this list without modifying the dictionary. A generical code example is the following:
class report:
def __init__(self):
self.dict_content= self.get_dict()
self.labels = self.get_labels()
def get_dict(self):
dict_content = dict(A1 = ['a', 'b', 'c'], A2 = ['d', 'e', 'f'])
return dict_content
def get_labels(self):
labels = []
for item in self.dict_content.items():
new_items = item[1]
new_items.insert(0, item[0])
labels.append(new_items)
return labels
Calling in the console,
r = report()
labels = r.labels
print(labels)
[['A1', 'a', 'b', 'c'], ['A2', 'd', 'e', 'f']]
dict_content = r.dict_content
print(dict_content)
{'A1': ['A1', 'a', 'b', 'c'], 'A2': ['A2', 'd', 'e', 'f']}
If I comment the line self.labels = self.get_labels() and do the last operations, I get:
r = report()
dict_content = r.dict_content
print(dict_content)
{'A1': ['a', 'b', 'c'], 'A2': ['d', 'e', 'f']}
And what I expect it to be is:
r = report()
labels = r.labels
print(labels)
[['A1', 'a', 'b', 'c'], ['A2', 'd', 'e', 'f']]
dict_content = r.dict_content
print(dict_content)
{'A1': ['a', 'b', 'c'], 'A2': ['d', 'e', 'f']}
What is happening?
for item in self.dict_content.items():
new_items = item[1]
new_items.insert(0, item[0])
labels.append(new_items)
Here, new_items, despite its name, is not a new list, but a reference to the original list contained in dict_content.
By using its insert method, you modify this list, which is reflected when looking at dict_content later.
Instead of modifying the original list, you want to create a new list. For example, by concatenation:
for item in self.dict_content.items():
new_items = [item[0]] + item[1]
labels.append(new_items)

List of Dictionary Values

I have the dictionary as below:
tf ={1: ['a', 'b', 'c'], 2: ['d', 'x', 'y']}
I want to form the list of values as:
wrd_list = ['a', 'b', 'c', 'd', 'x', 'y']
I tried to do this by using the following code:
wrd_list = []
for k, v in tf.items():
for i in v:
word_list.append(i)
is there any efficient way to do this?
Using extend here is faster than append when you want to concatenate lists:
word_list = []
for v in tf.values():
word_list.extend(v)

Convert a list of list's names(str) into a list of lists in python [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 4 years ago.
I am new to python and I have search a lot about this issue. I know there is a way of converting tuples to a list, but somehow it doesn't work for me. Here is my issue.
Say I have:
l_1 = ['a','b','c']
l_2 = ['e','f','g']
l_3 = ['g','h','i']
Then say I have another list of:
l_all = ['l_1','l_2','l_3']
How can I convert it(l_all) to a list of
[['a','b','c'],['e','f','g'],['g','h','i']]
I tried ast package using ast.literal_eval, but I received this error:
ValueError: malformed node or string: <_ast.Name object at
0x00000172CA3C5278>
I also tried to use json package, still no luck.
I tried just output ast.literal_eval('l_1'), not working either.
I'd really appreciate if anyone can help on this.
Thanks a lot!
That sounds like a problem that should be fixed upstream
ast.literal_eval evaluates literals. eval is just 1) cheating and 2) so dangerous I wouldn't recommend it at all.
Anyway, you could scan global then local variables using global & local dicts in a list comprehension:
l_1 = ['a','b','c']
l_2 = ['e','f','g']
l_3 = ['g','h','i']
l_all = ['l_1','l_2','l_3']
l_all = [globals().get(x,locals().get(x)) for x in l_all]
result:
[['a', 'b', 'c'], ['e', 'f', 'g'], ['g', 'h', 'i']]
globals().get(x,locals().get(x)) is a quick & dirty code to first look in global vars & fallback to local vars if not found. It could be overcomplicated for your needs.
You can use a dictionary to store the list names and each associated list:
d = {'l_2': ['e', 'f', 'g'], 'l_3': ['g', 'h', 'i'], 'l_1': ['a', 'b', 'c']}
l_all = ['l_1','l_2','l_3']
final_results = [d[i] for i in l_all]
Output:
[['a', 'b', 'c'], ['e', 'f', 'g'], ['g', 'h', 'i']]
However, to actually access the lists via variable name, you would have to use globals:
l_1 = ['a','b','c']
l_2 = ['e','f','g']
l_3 = ['g','h','i']
l_all = ['l_1','l_2','l_3']
new_l = [globals()[i] for i in l_all]
Output:
[['a', 'b', 'c'], ['e', 'f', 'g'], ['g', 'h', 'i']]
You can simply do:
l_1 = ['a','b','c']
l_2 = ['e','f','g']
l_3 = ['g','h','i']
l_all = ['l_1','l_2','l_3']
print(list(map(lambda x:globals()[x],l_all)))
output:
[['a', 'b', 'c'], ['e', 'f', 'g'], ['g', 'h', 'i']]
Then say I have another list of:
l_all = ['l_1','l_2','l_3']
Let's say you don't create this using strings, and use the list variables directly
You can then get the wanted output
l_all = [l_1,l_2, l_3]
You can use locals()
l_1 = ['a','b','c']
l_2 = ['e','f','g']
l_3 = ['g','h','i']
l_all = ['l_1', 'l_2', 'l_3']
all_local_variables = locals()
l_all_values = [all_local_variables[i] for i in l_all]
And you should be aware that you can get KeyError if no such variable present in current scope, for that you can all_local_variables.get(i), that will return None if not present or set default as all_local_variables.get(i, 'default')
The simplest way to do this is to evaluate your strings in l_all. Something like this
>>> l_1 = ['a','b','c']
>>> l_2 = ['e','f','g']
>>> l_3 = ['g','h','i']
>>> l_all = ['l_1','l_2','l_3']
>>> [ eval(x) for x in l_all ]
The output is
[['a', 'b', 'c'], ['e', 'f', 'g'], ['g', 'h', 'i']]

Retrieving single dictionary element in Python [duplicate]

This question already has answers here:
In what order does python display dictionary keys? [duplicate]
(4 answers)
Closed 8 years ago.
I want to retrieve only the fourth item in the dictionary "e" (below).
I tried using the OrderedDict() method, but it didn't work. Here are my results:
from collections import OrderedDict
e = OrderedDict()
e = {'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E'
}
for k, v in e.items():
print k, v
print e.items()[3]
The last line returns: ('e', 'E')
So I turned the keys and values into lists, but here's how the lists appeared when I printed them:
['a', 'c', 'b', 'e', 'd']
['A', 'C', 'B', 'E', 'D']
For me, this explained why it happened, but not how it happened.
So, next I sorted them. That gave me the results I was looking for -- but it seemed unnecessarily complicated:
e = {'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E'
}
k, v = sorted(e.keys()), sorted(e.values())
print "{}: {}".format(k[3], v[3])
Result:
d: D
OrderedDict() wasn't necessary.
Is there an easier way to do this? And can someone explain why the elements in the dictionary are ordered like this:
keys: 'a', 'c', 'b', 'e', 'd'
values: 'A', 'C', 'B', 'E', 'D'
... which defies the structure of my original dictionary?
You're not using an ordered dict.
e = OrderedDict()
e = {'a': 'A',
'b': 'B',
'c': 'C',
'd': 'D',
'e': 'E'
}
The first line creates an OrderedDict. The second line throws it away and replaces it with a regular dict, which is unordered. (Python variables don't have types.)
But you can't just do this:
e = OrderedDict({'a': 'A', ...})
...because that's still a regular dict, which is still unordered, and OrderedDict can't magically recreate your original source ordering.
Try this:
e = OrderedDict([('a', 'A'), ('b', 'B'), ...])
Now you should have a dict-like object with the ordering you want.
And can someone explain why the elements in the dictionary are ordered like this ... which defies the structure of my original dictionary?
Because dictionaries are unordered. They're just hash maps, and hash maps have no inherent ordering.
Note that you could also do this, which will preserve the pairing of keys and values (whereas your separate sortings will not):
print sorted(e.items())[3]

Categories

Resources