How to fill a dictionary in python? - python

I have a list of lists like so: N = [[a,b,c],[d,e,f],[g,h,i]]
I would like to create a dictionary of all the first values of each list inside N so that I have;
d = {1:[a,d,g],2:[b,e,h],3:[c,f,i]}
I have tried many things and I cant figure it out. The closest I have gotten:
d = {}
for i in range(len(N)):
count = 0
for j in N[i]:
d[count] = j
count+=1
But this doesnt give me the right dictionary? I would really appreciate any guidance on this, thank you.

You can use a dict comprehension (I use N with 4 items, to avoid confusion):
N=[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'],['w', 'j', 'l']]
{i+1:[k[i] for k in N] for i in range(len(N[0]))}
#{1: ['a', 'd', 'g', 'w'], 2: ['b', 'e', 'h', 'j'], 3: ['c', 'f', 'i', 'l']}

You can transpose the list with zip(*N) and then use enumerate to get the index and the elements into pairs for dict.
>>> dict((i+1, list(j)) for i, j in enumerate(zip(*N)))
{1: ['a', 'd', 'g'], 2: ['b', 'e', 'h'], 3: ['c', 'f', 'i']}
Alternate based on suggestion by #Vishal Singh
>> dict((i, list(j)) for i, j in enumerate(zip(*N), start=1))

Check the provided code below and output.
N = [[a,b,c],[d,e,f],[g,h,i]]
d = {}
for y in range(0,len(N)):
tmp=[]
for x in N:
tmp.append(x[y])
d[y+1]=tmp
//Output:
{1: [a, d, g], 2: [b, e, h], 3: [c, f, i]}
Hope that helps!

Here is a simple solution. Just pass your list to this function.
def list_to_dict(lis):
a=0
lis2=[]
dict={}
n=len(lis)
while a<n:
for el in lis:
lis2.append(el[a])
dict[a+1]=lis2
lis2=[]
a+=1
return dict
my_list=[["a","b","c"],["d","e","f"],["g","h","i"]]
print(list_to_dict(my_list))

Related

How to group elements in a list in with respect to another list in Python3?

I have 2 lists
in1=[1,1,1,2,2,3,4,4,4,5,5]
in2=['a','b','c','d','e','f','g','h','i','j','k']
I want to group the second list based on the same elements in the first list i.e.
Output has to be
out=[['a','b','c'],['d','e'],['f'],['g','h','i'],['j','k']]
Explanation: the first 3 elements of the first list are the same, so I want the first 3 elements of the 2nd list to be grouped together (and so on)
If anyone can help out, it would be great!
~Thanks
Just zip the lists, then itertools to the rescue.
from itertools import groupby
in1 = [1,1,1,2,2,3,4,4,4,5,5]
in2 = ['a','b','c','d','e','f','g','h','i','j','k']
result = [[c for _, c in g] for _, g in groupby(zip(in1, in2), key=lambda x: x[0])]
print(result)
# [['a', 'b', 'c'], ['d', 'e'], ['f'], ['g', 'h', 'i'], ['j', 'k']]
Non-itertools solution:
in1 = [1,1,1,2,2,3,4,4,4,5,5]
in2 = ['a','b','c','d','e','f','g','h','i','j','k']
result = [[]]
key = in1[0]
for k, v in zip(in1, in2):
if k != key:
result.append([])
key = k
result[-1].append(v)
print(result)
# [['a', 'b', 'c'], ['d', 'e'], ['f'], ['g', 'h', 'i'], ['j', 'k']]

Get indexes that list items start to change

I have a list that contains number of strings that change after several consecutive repetitions of a string. Let me explain with an example: If I have this string
lst = ['A', 'A', 'A', 'A', 'F', 'F', 'F', 'F', 'D', 'G', 'G', 'G', 'W']
I want to get a list of items where the elements in that index have started to change (including the first item list), so the output should be like this:
out = [0, 4, 8, 9, 10]
How can I do this in the best possible way?
[i for i, z in enumerate(lst) if z != lst[i - 1] or i == 0]
haven't tested this, but it should work I believe.
Here's a for loop that can get the job done for you. It iterates through the list and checks to see if each value it contains is different from the previous one it identified. If so, it adds the index to a list and updates its curr_val.
lst = ['A', 'A', 'A', 'A', 'F', 'F', 'F', 'F', 'D', 'G', 'G', 'G', 'W']
def find_change(lst):
curr_val = ''
indices = []
for i,v in enumerate(lst):
if curr_val != v:
indices.append(i)
curr_val = v
return indices
i = find_change(lst)
print(i)

Iterate lists at intervals based on list values

I've been trying to accomplish this in a few different ways and just can't quite seem to get it to work for me.
I'm trying to iterate over a list in blocks, where the first index value is an integer for how many elements are in the first block. After that, another integer with n elements, and another, etc.
Example:
test = [3, 'a', 'b', 'c', 2, 'd', 'e', 3, 'f', 'g', 'h']
I want to read 3, pull 'a', 'b', 'c' from the list and perform some operation on them.
Then return to the list at 2, pull 'd', 'e' - more operations, etc.
Or even just using the integers to split into sub-lists would work.
I'm thinking list slicing with updated [start:stop:step] variables but am having trouble pulling it together.
Any suggestions?
Can only use the standard Python library.
You could create a generator to iterate lazily on the parts of the list:
test = [3, 'a', 'b', 'c', 2, 'd', 'e', 3, 'f', 'g', 'h']
​
def parts(lst):
idx = 0
while idx < len(lst):
part_length = lst[idx]
yield lst[idx+1: idx + part_length + 1 ]
idx += part_length+1
for part in parts(test):
print(part)
Output:
['a', 'b', 'c']
['d', 'e']
['f', 'g', 'h']
If your input structure is always like this you can do the following:
result = [test[i:i+j] for i, j in enumerate(test, 1) if isinstance(j, int)]
print(result)
# [['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h']]
Using an iterator on the list makes this super simple. Just grab the next item which tells you how much more to grab next, and so on until the end of the list:
test = [3, 'a', 'b', 'c', 2, 'd', 'e', 3, 'f', 'g', 'h']
it = iter(test)
for num in it:
print(", ".join(next(it) for _ in range(num)))
which prints:
a, b, c
d, e
f, g, h
You can also convert this to a list if you need to save the result:
>>> it = iter(test)
>>> [[next(it) for _ in range(num)] for num in it]
[['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h']]

Make a list based on conditions in python to create a unique list

I have two lists:
a= [0,0,0,1,1,1,3,3,3]
b= ['a','b','c','d','e','f','g','h','i']
output = [['a','b','c'],['d','e','f'],['g','h','i']]
a and b are list of same length.
I need an output array by in such a way that whenever the value in list - a changes from 0 to 1 or from 1 to 3, A new list should be made in the output list.
can someone please help.
Use groupby:
from itertools import groupby
from operator import itemgetter
a = [0, 0, 0, 1, 1, 1, 3, 3, 3]
b = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
output = [list(map(itemgetter(1), group)) for _, group in groupby(zip(a, b), key=itemgetter(0))]
print(output)
Output
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
A simpler method without using any imports by utilizing dictionary:
a= [0,0,0,1,1,1,3,3,3]
b= ['a','b','c','d','e','f','g','h','i']
d = {e: [] for e in set(a)} # Create a dictionary for each of a's unique key
[d[e].append(b[i]) for i, e in enumerate(a)] # put stuff into lists by index
lofl = list(d.values())
>>> lofl
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
Using groupby, you could do:
from itertools import groupby
a= [0,0,0,1,1,1,3,3,3]
b= ['a','b','c','d','e','f','g','h','i']
iter_b = iter(b)
output = [[next(iter_b) for _ in group] for key, group in groupby(a)]
print(output)
# [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
groupby yields successive groups of identical values of a. For each group, we create a list containing as many of the next elements of b as there are values in the group.
As you added tag algorithm , I believe you want a solution without so many magic.
>>> def merge_lists(A, B):
... output = []
... sub_list = []
... current = A[0]
... for i in range(len(A)):
... if A[i] == current:
... sub_list.append(B[i])
... else:
... output.append(sub_list)
... sub_list = []
... sub_list.append(B[i])
... current = A[i]
... output.append(sub_list)
... return output
...
>>> a= [0,0,0,1,1,1,3,3,3]
>>> b= ['a','b','c','d','e','f','g','h','i']
>>> merge_list(a, b)
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]

Putting values of same dictionary keys in one group in python

I have two lists:
list1=[0,0,0,1,1,2,2,3,3,4,4,5,5,5]
list2=['a','b','c','d','e','f','k','o','n','q','t','z','w','l']
dictionary=dict(zip(list1,list2))
I would like to output values of the same keys in one for each key such as it will print like this:
0 ['a','b','c']
1 ['d','e']
2 ['f','k']
3 ['o','n']
4 ['q','t']
5 ['z','w','l']
I wrote following code to do that but it does not work as I think
for k,v in dictionary.items():
print (k,v)
Could you tell me how to fix code so that I can get above intended results, please ?
Thanks in advance!
Regarding your code:
dictionary = dict(zip(list1, list2))
creates the dictionary:
{0: 'c', 1: 'e', 2: 'k', 3: 'n', 4: 't', 5: 'l'}
which loses all but the last value in each group. You need to process the zipped lists to construct the grouped data. Two ways are with itertools.groupby() or with a defaultdict(list), shown here.
Use a collections.defaultdict of lists to group the items with keys from list1 and values from list2. Pair the items from each list with zip():
from collections import defaultdict
list1=[0,0,0,1,1,2,2,3,3,4,4,5,5,5]
list2=['a','b','c','d','e','f','k','o','n','q','t','z','w','l']
d = defaultdict(list)
for k,v in zip(list1, list2):
d[k].append(v)
for k in sorted(d):
print('{} {!r}'.format(k, d[k]))
Output:
0 ['a', 'b', 'c']
1 ['d', 'e']
2 ['f', 'k']
3 ['o', 'n']
4 ['q', 't']
5 ['z', 'w', 'l']
Since items in a dictionary are unordered, the output is sorted by key.
The code you've shown does not look anything like what you described.
That aside, you can group values of the same key together by first zipping the lists and then grouping values of the same key using a collections.defaultdict:
from collections import defaultdict
d = defaultdict(list)
for k, v in zip(list1, list2):
d[k].append(v)
print(d)
# defaultdict(<type 'list'>, {0: ['a', 'b', 'c'], 1: ['d', 'e'], 2: ['f', 'k'], 3: ['o', 'n'], 4: ['q', 't'], 5: ['z', 'w', 'l']})
You can use itertool.groupby for a concise, one line solution:
import itertools
list1=[0,0,0,1,1,2,2,3,3,4,4,5,5,5]
list2=['a','b','c','d','e','f','k','o','n','q','t','z','w','l']
final_list = {a:[i[-1] for i in list(b)] for a, b in itertools.groupby(zip(list1, list2), key=lambda x: x[0])}
for a, b in final_list.items():
print(a, b)
Output:
0 ['a', 'b', 'c']
1 ['d', 'e']
2 ['f', 'k']
3 ['o', 'n']
4 ['q', 't']
5 ['z', 'w', 'l']

Categories