Searching for duplicate values in a multiple 2D arrays - python

I am figuring to get a method to search the duplicated parts in a 2D array in Python.
Taking the below array for example:
Array1 = [[1, 7], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7]]
Array2 = [[5, 8], [5, 7], [5, 6], [5, 5], [5, 4]]
Array3 = [[1, 7], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7]]
ArrayN = [......]
the result I would like to get is like this:
Array_result = [[5,7]]
Is there any method that can automatically search the duplicated areas and save the coordinates?

Here is one way to do so, converting lists to set().
data = [
[[1, 7], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7]],
[[5, 8], [5, 7], [5, 6], [5, 5], [5, 4]],
[[1, 7], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7]],
]
arr_result = set(tuple(x) for x in data[0])
for arr in data[1:]:
arr_result.intersection_update(tuple(x) for x in arr)
print(arr_result) # {(5, 7)}
As each list contains sub-lists, they must be converted into tuples, because lists are unhashable.
We convert the first list to a set(), then for each list in data, we intersect the set and the list using intersection_update().
Using list comprehension:
arr_result = set.intersection(*[{tuple(x) for x in arr} for arr in data])
print(arr_result) # {(5, 7)}

Cubix48 solution using list comprehension should be preferred, use the below just as reference for other problems.
Using collections:
from collections import Counter
array_list = [[str(x) for x in array] for array in [Array1, Array2, Array3]]
c = Counter()
for item in array_list:
c.update(item)
repeated_items = [eval(item) for item in dict(c).keys() if c[item] == len(array_list)]

Related

how to execute a function on items in many nested lists in python

I want to iterate through a ton of nested lists in python, and recursively tree into other lists. The list(s) will have the general format [[1, [2, [3, [4, 5]]]], [7, [8, [9, [10, 11]]]]]. For example, I would want to make another nested list without flattening the big list.
Expected output: [[1, [2, [3, [4, [5, x]]]]], [7, [8, [9, [10, [11, y]]]]]]
I have tried function recursion, and have made the function getChildren():
def getChildren(list):
for item in list:
item = [item, item + 1]
return list
I believe that I am close. I want to do this all many times until a value at "the bottom".
So far, here's my code:
while True:
layer = []
for item in list:
item = getChildren(item)
layer.append(item)
list.append(layer)
But it's not working as expected. Any help?
Try:
L = [[1, [2, [3, [4, 5]]]], [7, [8, [9, [10, 11]]]]]
def getChildren(L):
for indx, value in enumerate(L):
if isinstance(value, list):
getChildren(value)
else:
L[indx] = [value, value + 1]
getChildren(L)
print(L)
gives:
[[[1, 2], [[2, 3], [[3, 4], [[4, 5], [5, 6]]]]], [[7, 8], [[8, 9], [[9, 10], [[10, 11], [11, 12]]]]]]
OR
L = [[1, [2, [3, [4, 5]]]], [7, [8, [9, [10, 11]]]]]
def getChildren(L):
if isinstance(L[1], list):
getChildren(L[1])
else:
L[1] = [ L[1], L[1]+1 ]
getChildren(L[0])
getChildren(L[1])
print(L)
which gives:
[[1, [2, [3, [4, [5, 6]]]]], [7, [8, [9, [10, [11, 12]]]]]]
[[1, [2, [3, [4, [5, [6, 7]]]]]], [7, [8, [9, [10, [11, [12, 13]]]]]]]
[[1, [2, [3, [4, [5, [6, [7, 8]]]]]]], [7, [8, [9, [10, [11, [12, [13, 14]]]]]]]]

How to populate (append) list in Python with elements, that appear multiple of 2 times

Let's say I have a list of of list of 2 elements [[1 , 2], ...] in Python. Now I need to get something like this:
[2, 2] [2, 3] [3, 4] [3, 5] [3, 6] [3, 7]
Second element always goes up by 1, first element too, but occurs 2^n (n>=1) times, before going up.
So next will be 8 lists with first element 4, which occurs 8 times, second element of the lists will go up from 8 to 15.
Maybe you can try nested for loops like below
def fn(n, x):
for i in range(2, n+1):
for j in range(2**(i-1), 2**i):
x.append([i, j])
return(x)
or
from math import log2,ceil
def fn(n,x):
[x.append([ceil(log2(i)),i-1]) for i in range(3,2**n+1)]
return(x)
such that
>>> fn(3, [[1,2]])
[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7]]
>>> fn(4, [[1,2]])
[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10], [4, 11], [4, 12], [4, 13], [4, 14], [4, 15]]
from math import log
initial_list = [[1,2]]
def extend_pattern(initial_list,n):
last_sublist = initial_list[-1]
first_element = last_sublist[0]
for i in range(n):
last_sublist = list(last_sublist)
if i != 0:
last_sublist[1] += 1
last_sublist[0] = first_element + int(log(i+2,2))
initial_list.append(last_sublist)
extend_pattern(initial_list,10)
print(initial_list)
#[[1, 2], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10], [4, 11]]
Sounds like a fun homework.
If you intend a function with an output like this:
[[1, 1], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6], [3, 7], [4, 8], [4, 9], [4, 10]]
then this
def populate(n):
left=1
right=1
temp=right*2
output=[]
for i in range(0,n):
output.append([left,right])
right+=1
if(right==temp):
left+=1
temp=right*2
return output
is one of plenty ways to do it.
If you meant starting with a list and n something like this should work:
def populate(inputlist,n):
left=inputlist[len(inputlist)-1][0]+1
right=inputlist[len(inputlist)-1][1]+1
temp=right*2
for i in range(0,n):
inputlist.append([left,right])
right+=1
if(right==temp):
left+=1
temp=right*2
return inputlist

How to remove lists from a list

I have created a list where within it I seek to eliminate only the lists whose first value is greater than the second value of it.
I tried creating a second list with the elements to remove but I think it is not the most optimal way.
#y = []
x = [[1, 4], [1, 6], [2, 5], [2, 7], [4, 8], [6, 5], [6, 7], [2, 6], [3, 7], [5, 8], [6, 4], [7, 5]]
for i in range(len(x)):
if x[i][0] > x[i][1]:
print(x[i])
# y.append(x[i])
Is there an optimal way to achieve this?
I want that when printing on screen you get the following:
[[1, 4], [1, 6], [2, 5], [2, 7], [4, 8], [6, 7], [2, 6], [3, 7], [ 5, 8]]
Best regards,
This should work:
y = [[a,b] for a,b in x if a <= b]
Testing:
>>> x = [[1, 4], [1, 6], [2, 5], [2, 7], [4, 8], [6, 5], [6, 7], [2, 6], [3, 7], [5, 8], [6, 4], [7, 5]]
>>> y = [[a,b] for a,b in x if a < b]
>>> y
[[1, 4], [1, 6], [2, 5], [2, 7], [4, 8], [6, 7], [2, 6], [3, 7], [5, 8]]
>>>
This modifies the original list:
for i, (a, b) in enumerate(x):
if a > b:
del x[i]
Creating a new list:
[v for v in x if v[0] <= v[1]]
Or elimination in place:
for i in range(len(x) - 1, -1, -1): # need to start at the end
if x[i][0] > x[i][1]:
x.pop(i)
>>> filtered = list(filter(lambda f: f[0] < f[1], x))
>>> print(filtered)
This will create a new list with the desired values, using the built in filter(function, iterable) function.

How to convert a list with duplicate elements into a linked list without?

I have a nested like this:
[5, 6], [5, 4], [5, 8], [2, 6], [6, 8], [1, 3]
What I want is a list with unique elements joined by the duplicate ones, like this:
[2, 6, 8], [1, 3]
and for
[5, 6], [5, 4], [5, 8]
this:
[5, [6, 4, 8]]
Overall result should look like this:
[[5, [6, 4, 8]], [2, 6, 8], [1, 3]]
What I tried doing was using the following algorithm from this question on the site
pairs_to_link = [[5, 6], [5, 4], [5, 8], [2, 6], [6, 8], [1, 3]]
dict_mapping = dict(pairs_to_link)
final_list = []
for link in dict_mapping.keys() - dict_mapping.values():
links = [link]
while link in dict_mapping:
link = dict_mapping[link]
links.append(link)
final_list.append(links)
print(final_list)
OUTPUT: [[1, 3], [2, 6, 8], [5, 8]]
and it does remove duplicates and also links them but not in a 'tree' manner that I want, i.e. it only works for [1,3],[2,6],[6,8] to make it like this [1,3],[2,6,8]

creating list n copies of lists

I need a list of lists, where entered the first two sublists manually, but the third until 5th list are copies of each other. How can I do the trick having to write the same list three times? This example does not what I want but instead produces a third sublist which is three times as long as I need it:
examplelist=[[1,2],[3,4],3*[5,6,7]]
>>>[[1, 2], [3, 4], [5, 6, 7, 5, 6, 7, 5, 6, 7]]
I want:
>>>[[1, 2], [3, 4], [5, 6, 7], [5, 6, 7], [5, 6, 7]]
You are probably best off doing this in a straightforward way:
l = [[1, 2], [3, 4]]
l.extend([5, 6, 7] for _ in range(3))
If you multiply a list of lists ([[5, 6, 7]] * 3 == [[5, 6, 7], [5, 6, 7], [5, 6, 7]]) you will end up with three references to the same list.
A couple of ways:
>>> [[1,2],[3,4]] + [[5,6,7]]*3
[[1, 2], [3, 4], [5, 6, 7], [5, 6, 7], [5, 6, 7]]
or
>>> examplelist=[[1,2],[3,4]]
>>> examplelist.extend([[5,6,7]]*3)
>>> examplelist
[[1, 2], [3, 4], [5, 6, 7], [5, 6, 7], [5, 6, 7]]
But note that the last 3 lists in the list will be the same:
>>> examplelist[-1][0] = 100
>>> examplelist
[[1, 2], [3, 4], [100, 6, 7], [100, 6, 7], [100, 6, 7]]
probably not what you want.
Python will add lists to get what you expect:
>>> examplelist=[[1,2],[3,4]]
>>> n=3
>>> examplelist+=[[5,6,7] for i in range(n)]
>>> examplelist
[[1, 2], [3, 4], [5, 6, 7], [5, 6, 7], [5, 6, 7]]
You can also create the structure described in one go since expressions are evaluated as the list is constructed:
>>> li=[[1,2,3]] + [[5,6,7] for i in range(n)] + [[7,8,9]]
>>> li
[[1, 2, 3], [5, 6, 7], [5, 6, 7], [5, 6, 7], [7, 8, 9]]
This should work:
>>> from itertools import repeat
>>> ex = [ [1,2], [3,4] ]
>>> ex.extend(repeat([5, 6, 7], 3))
>>> ex
>>> [[1, 2], [3, 4], [5, 6, 7], [5, 6, 7], [5, 6, 7]]

Categories