create a list of dictionaries from two lists of tuples - python

I have a set of tuples:
users = set(("test#a.com","password"),("test#b.com","password"))
but could be simplified to a set...and a list of tuples:
licences = [("test#a.com","22"),("test#a.com","23"),("test#b.com","12")]
For every entry of the list the username could be repeated with different "licence" values.
I need to build a list of dictionaries like this:
[{"user":"test#a.com", "licences":["22","23"]},{"user":"test#b.com", "licences":["12"]}]
What I've done so far is this:
licenzadiz = []
for num,user in enumerate(users):
licenzadiz.append({'user': user[0], 'licences': []})
for num2,licence in enumerate(licences):
if user[0] == licence[0]:
licenzadiz[num]['licences'].append(licence[1])
that is working well. BUT I wonder if there are more elegant solutions to my problem.

You can get fancy with nested default dicts:
from collections import defaultdict
items = [('A','1'),('A','3'),('A','2'),
('B','0'),('B','4'),('B','-1'),
('C','7'),('C','6'),('C','12')]
d = defaultdict(lambda: defaultdict(list))
for use,lic in items:
d[use]['username'] = use #<-- Overwrites each time an already known key is found, but thats ok
d[use]['licence'].append(lic)
#Just for printout
for use in d:
print d[use]
print d[use]['username']
print d[use]['licence']
Output:
defaultdict(<type 'list'>, {'username': 'A', 'licence': ['1', '3', '2']})
A
['1', '3', '2']
defaultdict(<type 'list'>, {'username': 'C', 'licence': ['7', '6', '12']})
C
['7', '6', '12']
defaultdict(<type 'list'>, {'username': 'B', 'licence': ['0', '4', '-1']})
B
['0', '4', '-1']

data = {}
for num2,(email, license) in enumerate(licenze):
data.setdefault(email,[]).append(license)
print data #dictionary of email:[licenses,..]
#or
print data.items() # if you want a list
I guess ... i think

Related

How to compare each element of multiple lists and return name of lists which are different

I am having multiple lists and I need to compare each list with one another and return the name of lists which are different. We need to consider value of elements in list irrespective of their position while comparing lists.
For example:-
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
Output:-
['Lis1','Lis2','Lis3','Lis4']
Thanks in advance.
Try this:
input_lists = {"Lis1": ['1', '2', '3'], "Lis2": ['1', '2'],
"Lis3": ['0', '1', '3'], "Lis4": [], "Lis5": ['1', '2']}
output_lists = {}
for k, v in input_lists.items():
if sorted(v) not in output_lists.values():
output_lists[k] = sorted(v)
unique_keys = list(output_lists.keys())
print(unique_keys) # ['Lis1', 'Lis2', 'Lis3', 'Lis4']
import itertools
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
k=[Lis1,Lis2,Lis3,Lis4,Lis5]
k.sort()
list(k for k,_ in itertools.groupby(k))
output
[[], ['0', '1', '3'], ['1', '2'], ['1', '2', '3']]
a simple way to implement
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
lis=[Lis1,Lis2,Lis3,Lis4,Lis5]
final=[]
for ele in lis:
if(ele not in final):
final.append(ele)
print(final)
with your given data you can use:
Lis1=['1','2','3']
Lis2=['1','2']
Lis3=['0','1','3']
Lis4=[]
Lis5=['1','2']
name_lis = {'Lis1': Lis1, 'Lis2': Lis2, 'Lis3': Lis3, 'Lis4': Lis4, 'Lis5': Lis5}
tmp = set()
response = []
for k, v in name_lis.items():
s = ''.join(sorted(v))
if s not in tmp:
tmp.add(s)
response.append(k)
print(response)
output:
['Lis1', 'Lis2', 'Lis3', 'Lis4']
name_lis dictionary contains the name of your list and the actual list, you are iterating over each list, and for each list, you are sorting the elements and then converting in a string, if the string was encountered before you know that the list is a duplicate if not you are adding the list to the response

Add values stored in a dictionary as a list of values

I've been searching online for a solution, but everything I've done hasn't been working so far. As the title says, I have a dictionary with a list of values stored in it. I need to add those values together. How would I go about doing that? There are about 1000+ keys and values in the dictionary too, this is just a small example.
{'10_Principles_of_Economics': ['13', '13'],'Advanced_ANOVA': ['2', '1', '1', '2'], 'Advanced_Classical_Mechanics': ['1', '1', '1', '1', '1', '1'], 'Agile_software_development': ['1', '2']}
This is what I tried:
def convert_to_dict(matches):
dictionary = dict()
[dictionary[t[0]].append(t[1]) if t[0] in (dictionary.keys())
else dictionary.update({t[0]: [t[1]]}) for t in matches]
print(dictionary)
return dictionary
def sum_dictionary(dictionary):
dd3 = {}
for key in dictionary:
dd3[key] = [sum(dictionary[key])]
I know there is something wrong here, but I'm not completely sure what. Any help would be appreciated.
This should do:
dd4 = {k:sum([int(v) for v in val]) for k,val in dd3.items()}
Output:
{'10_Principles_of_Economics': 26,
'Advanced_ANOVA': 6,
'Advanced_Classical_Mechanics': 6,
'Agile_software_development': 3}
Your final function would look like this:
def sum_dictionary(dictionary):
return {k:sum([int(v) for v in val]) for k,val in dictionary.items()}
Please tell me if there's something you don't understand. Be careful to use the same variables in your function definition as the ones inside it.
If you want the sum on a list as strings (as stated in your comment), just change this:
{k:[str(sum([int(v) for v in val]))] for k,val in d.items()}
Output 2:
{'10_Principles_of_Economics': ['26'],
'Advanced_ANOVA': ['6'],
'Advanced_Classical_Mechanics': ['6'],
'Agile_software_development': ['3']}
somethig like this:
d = {
'10_Principles_of_Economics': ['13', '13'],
'Advanced_ANOVA': ['2', '1', '1', '2'],
'Advanced_Classical_Mechanics': ['1', '1', '1', '1', '1', '1'],
'Agile_software_development': ['1', '2']
}
Python 3.x
for key, value in d.items():
d[key] = [str(sum([int(x) for x in value]))]
print (d)
Python 2.x
for key, value in d.iteritems():

Double Nesting defaultdict

Poked around but couldn't figure it out, probably a very simple solution but please help me understand.
Source (sample.txt):
1,1,2,3
2,3,2,4,4
This:
import csv
from collections import defaultdict
input = "sample.txt"
with open(input) as f:
r = csv.reader(f)
d = defaultdict(list)
rlabel = 1
for row in r:
d[rlabel].append(row)
rlabel += 1
print(d)
Gets This:
defaultdict(<class 'list'>, {1: [['1', '1', '2', '3']], 2: [['2', '3', '2', '4', '4']]})
Why are there double brackets around my lists?
Why are there double brackets around my lists?
Your code works exactly as expected. The key point is the usage of extend and append.
append adds the parameter you passed as a single element. Due to a list is an object and your defaultdict class is list, so the list is appended as a list of lists.
extend method iterate in the input and extend the original list by adding all elements from an iterable.
So, in this case, if you want to add a single list to your defaultdict you should use list.extend method. And your output will be:
defaultdict(<class 'list'>, {1: ['1', '1', '2', '3'], 2: ['2', '3', '2', '4', '4']})
With a defaultdict, when a key is created a default value is associated to it
>>> d = defaultdict(list)
>>> 'a' in d[1]
False
>>> d
defaultdict(<class 'list'>, {1: []})
Given that your row is a list, you are appending a list to the list associated with the key.
To add the elements you can do
d[rlabel]+= row

How can I remove a value in this list if it is not inside one of the keys of this nested dictionary?

Currently, I have the following weird nested dictionary:
d = {'start': {'0': {'start', 'near'}, '1': {'start'}}, 'near': {'1': {'end'}}, 'end': {}}
And the following list:
l = ['1', '0', '1', 'x', '0', '1']
If one of the values in l are not in one of the keys and values in the dictionary, remove it from the list.
So for example, in the list, there is an "x" and I am trying to see if there is anyway I can remove it with either l.remove() or if del / pop is better.
The thing that is giving me troubles is the dictionary.
What I have going so far:
d = {'start': {'0': {'start', 'near'}, '1': {'start'}}, 'near': {'1': {'end'}}, 'end': {}}
l = ['1', '0', '1', 'x', '0', '1']
for key, value in d.items():
for keys, values in value.items():
for number in l:
Get the set of keys:
keys = set.union(*[set(x.keys()) for x in d.values()])
#{'0', '1'}
Filter out the non-keys:
result = [item for item in l if item in keys]
#['1', '0', '1', '0', '1']

Dictionary from two lists

I've been looking to create a dictionary from two set lists. I understand how to do this if I want each item in each list to be marked key and value for example:
list_one = ['a', 'b', 'c']
list_two = ['1', '2', '3']
dictionary = dict(zip(list_one, list_two))
print dictionary
{'a': 1, 'b': 2, 'c': 3}
However I'm looking to use all the items in list_two as values for the first item in list_one. This would then hit another loop and item in list_one will change and so will the items in list_two.
Hope this makes sense.
Any ideas would be appreciated.
Code used to create lists
def local_file(domain, user_list):
cmd = subprocess.check_output(["tasklist", "/V", "/FO", "CSV"])
tasks = csv.DictReader(cmd.splitlines(), dialect="excel")
image_name = set()
users = set()
for task in tasks:
if task['User Name'] == 'N/A': continue
task_domain, task_user = task['User Name'].split('\\')
if task_user in task['User Name']:
image_name.add(task['Image Name'])
else:
pass
if domain == task_domain and task_user in user_list:
users.add(task['User Name'])
sorted(image_name)
print "Users found:\n"
print '\n'.join(users)
print "\nRuning the following services and applications.\n"
print '\n'.join(image_name)
if arguments['--app'] and arguments['--output'] == True:
keys = users
key_values = image_name
dictionary = dict(zip(list_one, list_two))
print dictionary
elif arguments['--output'] == True:
return users
else:
pass
I guess you're looking for something like this:
>>> list_one = ['a', 'b', 'c']
>>> list_two = ['1', '2', '3']
>>> {item: list_two[:] for item in list_one}
{'c': ['1', '2', '3'], 'b': ['1', '2', '3'], 'a': ['1', '2', '3']}
For Python 2.6 and earlier:
>>> dict((item, list_two[:]) for item in list_one)
{'c': ['1', '2', '3'], 'b': ['1', '2', '3'], 'a': ['1', '2', '3']}
Note that [:] is required to create a shallow copy of the list, otherwise all values will point to the same list object.
Update:
As per your comment list_two will change during the iteration, here I've used an iterator to get the new value for list_two during the iteration:
>>> out = {}
>>> it = iter([['1', '2', '3'], ['5', '6', '7'], ['8', '9', '10']])
>>> list_two = next(it) #here `next` can be your own function.
>>> for k in list_one:
out[k] = list_two
list_two = next(it) #update list_two with the new value.
>>> out
{'c': ['8', '9', '10'], 'b': ['5', '6', '7'], 'a': ['1', '2', '3']}
#or
>>> it = iter([['1', '2', '3'], ['5', '6', '7'], ['8', '9', '10']])
>>> out = {}
>>> for k in list_one:
list_two = next(it) #fetch the value of `list_two`
out[k] = list_two
We don't know what's updating list two. Until we do, we can only guess. Idiomatically, whatever gets the values should be an iterable (so that you can use next).
res = {}
for k in list_one:
res[k] = next(lists_two)
or
res = {k:next(lists_two) for k in list_one}
if you have Python 2.7 or higher.
For an example that would have the same result as your comment, using grouper from itertools recipes:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
lists_two = grouper(range(3*len(list_one)), 3)
res = {k:next(lists_two) for k in list_one}

Categories

Resources