Dictionary from two lists - python

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}

Related

Split list in python when same values occurs into a list of sublists

Using python, I need to split my_list = ['1','2','2','3','3','3','4','4','5'] into a list with sublists that avoid the same value. Correct output = [['1','2','3','4','5'],['2','3','4'],['3']]
Probably not the most efficient approach but effective nonetheless:
my_list = ['1','2','2','3','3','3','4','4','5']
output = []
for e in my_list:
for f in output:
if not e in f:
f.append(e)
break
else:
output.append([e])
print(output)
Output:
[['1', '2', '3', '4', '5'], ['2', '3', '4'], ['3']]
I assumed you are indexing every unique element with its occurrence and also sorted the result list to better suit your desired output.
uniques = list(set(my_list))
uniques.sort()
unique_counts = {unique:my_list.count(unique) for unique in uniques}
new_list = []
for _ in range(max(unique_counts.values())):
new_list.append([])
for unique,count in unique_counts.items():
for i in range(count):
new_list[i].append(unique)
The output for new_list is
[['1', '2', '3', '4', '5'], ['2', '3', '4'], ['3']]
By using collections.Counter for recognizing the maximum number of the needed sublists and then distributing consecutive unique keys on sublists according to their frequencies:
from collections import Counter
my_list = ['1','2','2','3','3','3','4','4','5']
cnts = Counter(my_list)
res = [[] for i in range(cnts.most_common(1).pop()[1])]
for k in cnts.keys():
for j in range(cnts[k]):
res[j].append(k)
print(res)
[['1', '2', '3', '4', '5'], ['2', '3', '4'], ['3']]
Here's a way to do it based on getting unique values and counts using list comprehension.
my_list = ['1','2','2','3','3','3','4','4','5']
unique = [val for i,val in enumerate(my_list) if val not in my_list[0:i]]
counts = [my_list.count(val) for val in unique]
output = [[val for val,ct in zip(unique, counts) if ct > i] for i in range(max(counts))]

Creating a list with specific values from a list of dictionaries (keys as strings and values are list of integers)

I have a list of dictionaries with a string and a list of strings as values for their respective keys:
list_of_dictionaries = [
{'id': 'ABBA', 'num': ['10', '3', '5', '1']},
{'id': 'ABAC', 'num': ['4', '5', '6', '20']}]
Each letter in the 'id' string corresponds with the number in 'num' at matching indices. So for value 'ABBA' it would match the value in 'num' at each position in order: A = 10, B = 3, B = 5, A = 1. I would like return a list of the ids with 'num' > 5 in each dictionary while maintaining their current order.
Here is my attempt:
bad_values = ['','0','1','2','3','4','5']
final_ids =[]
for i in list_of_dictionaries:
list_of_high_num =[]
for id,num in enumerate(i.items()):
if i["num"] is not bad_values:
list_of_high_num.append(i["id"])
final_ids.append(list_of_high_num)
However, I'm just getting my original string of ids back in a list. Where am I going wrong?
Desired output something like this:
final_list = [['A'], ['A', 'C']]
considering the scenario for each dictionary item len(id) = len(num)
list_of_dictionaries = [
{'id': 'ABBA', 'num': ['10', '3', '5', '1']},
{'id': 'ABAC', 'num': ['4', '5', '6', '20']}]
limit = 5
outerlist = []
for d in list_of_dictionaries:
innerlist = []
for x in range(len(d['num'])):
if int(d['num'][x]) > limit:
innerlist.append(d['id'][x])
outerlist.append(innerlist)
print(outerlist) # [['A'], ['A', 'C']]

Remove duplicates from a nested list

I have a list
A = [['1'],['1','2'],['1','2','3','1','2'],['3','3','3']]
and I want to make my list to
A = [['1'],['1','2'],['1','2','3'],['3']]
ie I want to remove duplicate elements within the elements in a list ..
One-liner (If order doesn't matter) :
A = [['1'],['1','2'],['1','2','3','1','2'],['3','3','3']]
A = [list(set(a)) for a in A]
print(A) # => [['1'], ['2', '1'], ['3', '2', '1'], ['3']]
One-liner (If order matters) :
A = [['1'],['1','2'],['1','2','3','1','2'],['3','3','3']]
A = [sorted(set(a), key=a.index) for a in A]
print(A) # => [['1'], ['1', '2'], ['1', '2', '3'], ['3']]
A functional version, with functools:
>>> import functools
>>> A = [['1'],['1','2'],['1','2','3','1','2'],['3','3','3']]
>>> print ([functools.reduce(lambda result,x:result if x in result else result+[x], xs, []) for xs in A])
[['1'], ['1', '2'], ['1', '2', '3'], ['3']]
The lambda function adds an element to the result list only if that element is not present in the list. Not very efficient, but keeps the order of elements.
Also note that with Python 2, you don't need to import functools: reduce is a builtin function.
You can use a generator:
def remove_dups(l):
for a in l:
new_l = []
for b in a:
if b not in new_l:
new_l.append(b)
yield new_l
A = [['1'],['1','2'],['1','2','3','1','2'],['3','3','3']]
print(list(remove_dups(A)))
Output:
[['1'], ['1', '2'], ['1', '2', '3'], ['3']]

create a list of dictionaries from two lists of tuples

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

split a key in a dic and its values to multiple keys/values

I have the following dic:
dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
I want to convert it to:
dic = {'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3'], 'item2': ['5', '6', '10'], 'item3': ['3', '7', '9']}
Basically, I want to split based on '_' and make new keys/values out of the original key and its values.
The size of the second key might have more items; for example 'item1_item2,item3,item4'.
Use zip() to pair up the split key and values; you'll want to build a new dictionary here:
new = {}
for key, value in dic.items():
if '_' not in key:
new[key] = value
continue
for new_key, new_value in zip(key.split('_'), value):
new[new_key] = new_value.split('_')
You could mash this in to a dictionary comprehension but it becomes rather harder to follow:
{nk: (nv.split('_') if '_' in k else v)
for k, v in dic.items() for nk, nv in zip(k.split('_'), v)}
Demo:
>>> dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
>>> new = {}
>>> for key, value in dic.items():
... if '_' not in key:
... new[key] = value
... continue
... for new_key, new_value in zip(key.split('_'), value):
... new[new_key] = new_value.split('_')
...
>>> new
{'item2': ['5', '6', '10'], 'item3': ['3', '7', '9'], 'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3']}
>>> {nk: (nv.split('_') if '_' in k else v)
... for k, v in dic.items() for nk, nv in zip(k.split('_'), v)}
{'item2': ['5', '6', '10'], 'item3': ['3', '7', '9'], 'shape': ['a', 'b', 'c'], 'item1': ['1', '2', '3']}
What you wanna do it's this:
Extract the key that you wanna split
split it and assign it to a new list
assing the values of the key to a list of the new list and append it to the new key
delete the old key and value
To get you started
dic = {item: "whatever", item1_item2_item3: [1,2,3], [2,3,4]. [4,5,6]}
copy = dic[item1_item2_item3]
name = item1_item2_item3
name = name.split("_")
#this make a list like this: [item1, item2, item3]
for i in len(name):
dic[name[i]] = copy[i]
del.dic[item1_item2_item3]
You can split string using my_string.split("_") to get a list strings. Here's one solution to split the strings and the keys and assign the new values:
dic = {'shape': ['a', 'b', 'c'], 'item1_item2_item3': ['1_2_3', '5_6_10', '3_7_9']}
new_dic = {}
for k in dic.keys():
val = dic[k]
subkeys = k.split("_")
if len(subkeys) > 1:
for s in range(len(subkeys)):
subkey = subkeys[s]
subvals = val[s].split("_")
new_dic[subkey] = subvals
# this handles the case where the key has no underscores
else:
new_dic[k] = val
print new_dic

Categories

Resources