How to merge two array and group by key? - python-3.x

How to merge two array and group by key?
Example:
my_list = [3, 4, 5, 6, 4, 6, 8]
keys = [1, 1, 2, 2, 3, 5, 7]
Expected outcome:
[[1, 3, 4], [2, 5, 6], [3, 4], [5, 6], [7, 8]]

If I understand it right, the list of keys map to the list of values. You can use the zip function to iterate through two lists at the same time. Its convenient in this case. Also check up on the beautiful defaultdict functionality - we can use it to fill a list without initialising it explicitely.
from collections import defaultdict
result = defaultdict(list) # a dictionary which by default returns a list
for key, val in zip(keys, my_list):
result[key].append(val)
result
# {1: [3, 4], 2: [5, 6], 3: [4], 5: [6], 7: [8]}
You can then go to a list (but not sure why you would want to) with:
final = []
for key, val in result.items():
final.append([key] + val) # add key back to the list of values
final
# [[1, 3, 4], [2, 5, 6], [3, 4], [5, 6], [7, 8]]

I think you have to write it by your own using set() to remove duplicates, so I have made a function called merge_group
my_list = [3, 4, 5, 6, 4, 6, 8]
keys = [1, 1, 2, 2, 3, 5, 7]
def merge_group(input_list : list, input_key : list):
result = []
i = 0
while i < len(my_list):
result.append([my_list[i], keys[i]])
i += 1
j = 0
while j < len(result):
if j+1 < len(result):
check_sum = result[j] + result[j+1]
check_sum_set = list(set(check_sum))
if len(check_sum) != len(check_sum_set):
result[j] = check_sum_set
j += 1
return result
print(merge_group(my_list, keys))

Related

Grouping list elements three by three with the second group starting from then literary the second list element

I would like to group list elements in groups of three and make the second element of the list to start the second group of elements for example;
arr = [1,2,3,4,5,6,7,8,9]
#expected output
output = [[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9]]
How do I do this with python?
You can just use a list comprehension -
[arr[i:i+3] for i in range(len(arr)-2)]
Hello dear friend try to create new lists then append them to another list:
arr = [1,2,3,4,5,6,7,8,9]
i = 0
b = []
while i <= len(arr) - 3:
a = [arr[i],arr[i+1],arr[i+2]]
b.append(a)
i += 1
print(b)
OUTPUT
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9]]

Appending an int key in a dictionary

I am trying to create a dictionary from the following lists:
link_i = [1, 1, 3, 3, 3, 4, 4, 5, 5, 6]
link_j = [2, 3, 1, 2, 5, 5, 6, 6, 4, 4]
link_i = [1, 1, 3, 3, 3, 4, 4, 5, 5, 6]
link_j = [2, 3, 1, 2, 5, 5, 6, 6, 4, 4]
nodes = [1, 2, 3, 4, 5, 6]
# Creating a dictionary containing nodes and their incoming links:
out_dict = {}
for i in nodes:
for j in range(0,len(link_i)):
if (link_i[j] == i):
if i not in out_dict:
out_dict[i] = link_j[j]
elif i in out_dict:
out_dict[i].append(link_j[j])
However, I am not able to append the key since it has the type int. I get the error:
line 21, in <module>
out_dict[i].append(link_j[j])
AttributeError: 'int' object has no attribute 'append'
I am trying to get the output as:
{1: [2, 3], 3: [1, 2, 5], 4: [5, 6], 5: [6, 4], 6: [4]}
To keep the code simple you can use a dict comprehension and set the default value for each node to empty list. With that you don't need to check if the node is already part of the dict and you can just append the links.
link_i = [1, 1, 3, 3, 3, 4, 4, 5, 5, 6]
link_j = [2, 3, 1, 2, 5, 5, 6, 6, 4, 4]
nodes = [1, 2, 3, 4, 5, 6]
# Creating a dictionary containing nodes and their incoming links:
# fill the dict with empty lists for each node
out_dict = {node: [] for node in nodes}
for i in nodes:
for j in range(0,len(link_i)):
if (link_i[j] == i):
# append link to the list for the node
out_dict[i].append(link_j[j])
The output then looks like this:
{1: [2, 3], 2: [], 3: [1, 2, 5], 4: [5, 6], 5: [6, 4], 6: [4]}
You need to change:
if i not in out_dict:
out_dict[i] = link_j[j]
to
if i not in out_dict:
out_dict[i] = [link_j[j]]
This is because after you first add key "i" to out_dict, you are assigning it a single value which is of type int. In order to be able to add to this, later on, it needs to be a mutatable data type such as a list which does have attribute append. This doesn't fix all your problems because even with this change you still don't get your desired output but it will allow you to debug further.

Iā€™m trying to flip every second sub list in a list of lists. Does any one have suggestions?

My_list= [[1,2,3],[4,5,6],[7,8,9]] ā€”ā€”ā€”-> [[1,2,3],[6,5,4],[7,8,9]]
I tried using this with out success :
for i my_list:
if my_list.index(i) != 0:
i = i[::-1]
Since Python for loops create local variables, you have to index into the outer list indexes and use % 2 == 1 to detect sublists with odd indexes.
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
for index, sublist in enumerate(my_list):
if index % 2 == 1:
my_list[index] = sublist[::-1]
print(my_list)
Outputs
[[1, 2, 3], [6, 5, 4], [7, 8, 9], [12, 11, 10]]
Another option (in addition to #DeepSpace answer) is using Python's slicing notation (link) and assigning to slice (link):
In this example, we create slice starting from index 1 and step 2 and assign reverse sublist to it:
my_list = [[1,2,3],[4,5,6],[7,8,9]]
my_list[1::2] = (v[::-1] for v in my_list[1::2])
print(my_list)
Prints:
[[1, 2, 3], [6, 5, 4], [7, 8, 9]]

What does a list next to a list mean?

I am confused about what does lists[outer_index][inner_index] do? I thought that when two lists are next to each other, it means the first list is the selected list and the second list indicates the index of the first list. However, that doesn't seem to be the case here.
def flatten(lists):
results = []
for outer_index in range(len(lists)): # outer index = 0, 1
for inner_index in range(len(lists[outer_index])): # inner_index = [0, 1, 2, 0, 1, 2, 3, 4, 5]
results.append(lists[outer_index][inner_index])
return results
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
print(flatten(n))
You are creating an list of lists (basically a table).
n = [[1, 2, 3],
[4, 5, 6, 7, 8, 9]]
If I do n[0][1] I am saying go to row 0 and grab the element in column 1.
Its better to think of it this way.
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
s = n[0] # Now s = [1,2,3], the first element in n
s[1] = 2 # Because I just grabbed the second element in [1,2,3]
# This is the same as
n[0][1]

Remove by index on nested list

I have a nested list:
x = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
I want to iterate over the list and return a new nested list with each list returned with one value missing. So:
new_x = [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]
I have this:
temp_list = []
y = 0
for i in x:
temp_list += i.remove(y)
y+=1
print(x)
But what's happening is each iteration is removing the indexed item so the list goes out of range.
list = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
for count, i in enumerate(list):
if len(i) > 0:
del i[count]
print(list)
For each sublist it deletes the element with an index equal to the index of the sublist
>>>[[2, 3, 4], [1, 3, 4], [1, 2, 4], [1, 2, 3]]
Hope this helps!
You have to use pop instead for remove. See this one:
In [46]: x = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
In [47]: new_list = [lst for ind, lst in enumerate(x) if lst.pop(ind)]
In [48]: new_list
Out[48]: [[2, 3, 4], [1, 3, 4], [1, 2, 4], [1, 2, 3]]
x = [[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
for i in range(0,len(x)):
for j in range (0,len(x)):
if(i==j):
del(x[i][j])
print(x)
new_x = [[2,3,4],[1,3,4],[1,2,4],[1,2,3]]
del(x[i][j]) is used to delete by index from list

Resources