python list of lists common elements iteration - python

list= [[5, 4, 6], [6, 4, 5], [7, 1, 2]]
I have the above list, I want to compare every list index like [5,4,6] with [6,4,5] and [7,1,2] i.e. with every other list index
and for output: if there exist any common elements between 2 indexes in comparision then I want to output in a format
"the first element of each index" along with any common elements in the index.
answer for this iteration would be [5,4,6] as 5 is the first element of the index in comparison, 6 is the first element of the index in comparison, 4 is the common element.
next compare [6, 4, 5] with [5,4,6] and [7,1,2] and the answer would be [6,5,4]
next compare [7,1,2] with [5,4,6] and [6, 4, 5] and the answer would be [7]
Please help, I have been trying for really long.
basically I want every list index to check for common elements with every other list index and if 2 list indexes have anything in common I want to get a new output list with the first element of both list indexes and common elements
final output= [[5,6,4],[6,5,4],[7]]

myL = [[5, 4, 6], [6, 4, 5], [7, 1, 2]]
newLi = []
for i in range(len(myL)):
tmpLi = []
firstList = myL[i]
for a in range(len(myL)):
if a != i:
secondList = myL[a]
inCommon = set(firstList).intersection(secondList)
if len(inCommon) != 0:
tmpLi.append(firstList[0])
tmpLi.append(secondList[0])
for b in inCommon:
if b not in tmpLi:
tmpLi.append(b)
if len(tmpLi) == 0:
tmpLi.append(firstList[0])
newLi.append(tmpLi)
print(newLi)

Related

How to add elements of list of linked list in straight order?

How can I add elements of list of linked list in straight order?
For example, I have list of linked list: [[1, 2, 3], [4, 5, 6], [7, 8]] and list new_list and I wanna add all the elements in order 1->2->3->...->7->8 but not in order 1->4->7->2->5->3->6->8. For second case I have code:
new_list = []
for array in lists:
while array:
new_list.append(array.val)
array = array.next
But how to modify it to get an order as at first case?
Ok so here's what I have simply done:
lists = [[1,2,3],[4,5,6],[7,8]]
new_list = []
for array in lists:
for i in array:
new_list.append(i)
print(new_list)
Output: [1,2,3,4,5,6,7,8]
I don't know why you were using array.next or array.val, however I think you can simply get the list and iterate over it's values and then append it without any problem.
My idea is, I use pop to get the value and then sort the array, you can try my code:
lists = [[1, 2, 3], [4, 5, 6], [7, 8]]
new_list = []
for array in lists:
while array:
new_list.append(array.pop())
new_list.sort()
So you will get the result which you want : [1, 2, 3, 4, 5, 6, 7, 8]

Remove duplicate elements from list when there are many duplicate elements are present

I'm trying to remove a duplicate element from a list, it is not able to remove it ("1"), can somebody explain what I'm doing wrong
lst=[1,2,3,4,1,1,1,5,6,7,1,2]
for i in lst:
print(i)
if i==1:
lst.remove(i)
expected output -
[2,3,4,5,6,7,2]
actual output -
[2,3,4,5,6,7,1,2]
Using list comprehension:
Ex.
lst=[1,2,3,4,1,1,1,5,6,7,1,2]
new_list = [x for x in lst if x != 1]
print(new_list)
O/P:
[2, 3, 4, 5, 6, 7, 2]
OR
Remove all duplicate element from list, use set
Ex.
lst=[1,2,3,4,1,1,1,5,6,7,1,2]
print(list(set(lst)))
O/P:
[1, 2, 3, 4, 5, 6, 7]

Merge pairs on common integer with restrictions

I need an efficient way to merge a list of nodes (pairs of integers).
The merge should happen only if there is one common number in the pair and the common number is on the first or the last position (otherwise its allready connected).
For example:
mylist = [[4, 3], [6, 3]]
merge_links(mylist) # should output [4, 3, 6]
another example:
mylist = [[4, 3], [6, 3], [6, 4]]
merge_links(mylist)
# should output again [4, 3, 6] because both 6 and 4 allready exist in array.
and yet another example:
mylist = [[4, 3], [6, 3], [6, 4], [6, 2], [7, 4], [4, 9]]
merge_links(mylist)
# should output [7, 4, 3, 6, 2]
# [4, 3] ✔
# [4, 3] + [6, 3] ✔ -> [4, 3, 6]
# [4, 3, 6] + [6, 3] ✘ both 6 and 3 exist in [4, 3, 6]
# [4, 3, 6] + [6, 4] ✘ both 6 and 4 exist in [4, 3, 6]
# [4, 3, 6] + [6, 2] ✔ -> [4, 3, 6, 2]
# [4, 3, 6, 2] + [7, 4] ✔ -> [7, 4, 3, 6, 2]
# [7, 4, 3, 6, 2] + [4, 9] ✘ 4 is allready connected "7-4-3"!
Currently I'm using:
def merge_links(a, b):
inter = np.intersect1d(a, b, True)
a = set(a) - set(inter)
b = set(b) - set(inter)
n = np.unique(list(a) + list(inter) + list(b))
return n
But it doesnt work well for the above restrictions
The code below works as follows:
Create a new list with size of old list + 1 (The maximum size the
output can reach).
Start with the first pair in your list of pairs with its first value
at the end of your new list, and its second value at the start of
your new list. And mark them as visited using a python dictionary
for example.
Maintain two indexes of your first and last positions pointing to
the end and start of your new list respectively initially.
Iterate on the rest of pairs, if for pair i its both values exist or
don't exist in the dictionary, skip it. Else, merge the not visited
value to element at the first index or the last index (depending on
the position of the visited value), and update your index. Note that
no merging will happen if the visited value is not at the first or
the last index (if it is somewhere in the middle).
Return a concatenation of new list[first index to end] with new
list[start to the last index].
Note: every merging operation takes O(1). Also you can use an array of booleans instead of dictionary if you know the range of pairs values.
#The function takes a list of pairs as an argument
def merge_lst(lst):
#Dictionary to check if value is already in array
visited = dict()
#Length of old list
lst_len = len(lst)
#New list will have at most lst_len+1 elements
new_lst = [0]*(lst_len+1)
#Put the first pair values in last and first elements of the new list repectively and mark them as visited
new_lst[lst_len], new_lst[0] = lst[0][0], lst[0][1]
visited[lst[0][0]], visited[lst[0][1]] = True, True
#Maintain the positions of your first and last elements, which are the the last index and 0 respectively now
first_index, last_index = lst_len, 0
#Iterate on the rest of pairs
for i in range(1, lst_len):
#Check if pair[a, b] are already visited
a_exists, b_exists = lst[i][0] in visited, lst[i][1] in visited
#Skip if they both exist or don't exist
if(a_exists == b_exists):
continue
#Assume a was the common one
common, to_merge = lst[i][0], lst[i][1]
#If b exists (b is the common not a), then just swap
if(b_exists):
common, to_merge = lst[i][1], lst[i][0]
#If the common element is at the first index, the first element and index are updated
if(new_lst[first_index] == common):
first_index-=1
new_lst[first_index] = to_merge
visited[to_merge] = True
#If the common element is at the last index, the last element and index are updated
elif(new_lst[last_index] == common):
last_index+=1
new_lst[last_index] = to_merge
visited[to_merge] = True
#Else, the common element is somewhre in the middle (already connected)
#Return concatenation of new_lst[first_index to the end] with new_lst[0 to the last_index]
return new_lst[first_index:lst_len+1]+new_lst[0:last_index+1]
This code gives correct output for all of your mentioned test cases.

Slicing element from sublist - Python

I want to return the number 5 from this:
list_1 = [[1, 2, 3], [4, 5, 6]]
I thought this would work but it is not:
print(list_1[1:1])
It returns an empty list. It is Index 1 (second list) and position 1 (second number in the list).
Shouldn't that work?
You need two separate operations:
sub_list = list_1[1]
item = sub_list[1]
# or shortly list_1[1][1]
What you did was calling the slice interface which has an interface of [from:to:step]. So it meant: "give me all the items from index 1 to index 1" (read about slicing for more information).
list_1 = [[1, 2, 3], [4, 5, 6]]
then
list_1[0] == [1,2,3]
list_1[1] == [4,5,6]
then
list_1[1][1:1] == [] #slice starting from position '1', and around to the position before '1', effectively returning an empty list
list_1[1][1] == 5
edit corrections as from comments
list_1[1][1]
The first [1] gives you [4, 5, 6]. The next [1] gives you 5
Let's say we have a list:
list_1 = [[1, 2, 3], [4, 5, 6]]
You're question asks, why does
list_1[1:1]
Return []?
Because you're asking for the objects from index 1 to index 1, which is nothing.
Take a simple list:
>>> x = [1, 2, 3]
>>> x[1:1]
[]
This is also empty because you're asking for all objects from index 1 to index 1.
All the 2nd number does is say the maximum reach non-inclusive. So...
>>> x = [1, 2, 3]
>>> x[1:10000]
[2, 3]
>>> x[1:-1023]
[]
>>> x[1:2]
[2]
If the 1st number is equal to or greater than the 2nd number, you'll always end up with an empty list unless you change the step of the slice (if it's equal, it'll always be empty)
Of a 2-dimensional array, if you wanted the 2nd object of the 2nd list in the list:
>>> list_1[1]
[4, 5, 6]
>>> list_1[1][1]
5

Remove a column from a nested list in Python

I need help figuring how to work around removing a 'column' from a nested list to modify it.
Say I have
L = [[1,2,3,4],
[5,6,7,8],
[9,1,2,3]]
and I want to remove the second column (so values 2,6,1) to get:
L = [[1,3,4],
[5,7,8],
[9,2,3]]
I'm stuck with how to modify the list with just taking out a column. I've done something sort of like this before? Except we were printing it instead, and of course it wouldn't work in this case because I believe the break conflicts with the rest of the values I want in the list.
def L_break(L):
i = 0
while i < len(L):
k = 0
while k < len(L[i]):
print( L[i][k] , end = " ")
if k == 1:
break
k = k + 1
print()
i = i + 1
So, how would you go about modifying this nested list?
Is my mind in the right place comparing it to the code I have posted or does this require something different?
You can simply delete the appropriate element from each row using del:
L = [[1,2,3,4],
[5,6,7,8],
[9,1,2,3]]
for row in L:
del row[1] # 0 for column 1, 1 for column 2, etc.
print L
# outputs [[1, 3, 4], [5, 7, 8], [9, 2, 3]]
If you want to extract that column for later use, while removing it from the original list, use a list comprehension with pop:
>>> L = [[1,2,3,4],
... [5,6,7,8],
... [9,1,2,3]]
>>>
>>> [r.pop(1) for r in L]
[2, 6, 1]
>>> L
[[1, 3, 4], [5, 7, 8], [9, 2, 3]]
Otherwise, just loop over the list and delete the fields you no longer want, as in arshajii's answer
You can use operator.itemgetter, which is created for this very purpose.
from operator import itemgetter
getter = itemgetter(0, 2, 3) # Only indexes which are needed
print(list(map(list, map(getter, L))))
# [[1, 3, 4], [5, 7, 8], [9, 2, 3]]
You can use it in List comprehension like this
print([list(getter(item)) for item in L])
# [[1, 3, 4], [5, 7, 8], [9, 2, 3]]
You can also use nested List Comprehension, in which we skip the elements if the index is 1, like this
print([[item for index, item in enumerate(items) if index != 1] for items in L])
# [[1, 3, 4], [5, 7, 8], [9, 2, 3]]
Note: All these suggested in this answer will not affect the original list. They will generate new lists without the unwanted elements.
Use map-lambda:
print map(lambda x: x[:1]+x[2:], L)
Here is one way, updated to take in kojiro's advice.
>>> L[:] = [i[:1]+i[2:] for i in L]
>>> L
[[1, 3, 4], [5, 7, 8], [9, 2, 3]]
You can generalize this to remove any column:
def remove_column(matrix, column):
return [row[:column] + row[column+1:] for row in matrix]
# Remove 2nd column
copyofL = remove_column(L, 1) # Column is zero-base, so, 1=second column
when you do the del it will delete that index and reset the index, so you have to reduce that index. Here I use the count to reduce and reset the same from the index list we have. Hope this helps. Thanks
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
remove_cols_index = [1,2]
count = 0
for i in remove_cols_index:
i = i-count
count = count+1
del nested_list[i]
print (nested_list)
[j.pop(1) for j in nested_list]
from https://www.geeksforgeeks.org/python-column-deletion-from-list-of-lists/

Categories