So I have function below that checks to see if any element of list a is the subset of any other element in the same list, and it returns only those indexes that are subsets.
a = [[1,2,3,4],
[2,3],
[1,5,7,8],
[5],
[7,8],
[1,2,3],
[7,8,9]]
#we need to keep [0,2,6]
#we need to remove [1,3,4,5]
def indexes_to_remove(array):
def boolMatrix(array):
boole = []
d ={}
for i,m in enumerate(array):
d[i] = []
for j in array:
boole.append(set(m).issubset(j))
return np.array(boole).reshape(len(array),len(array)) #True equals "is subset"
b= boolMatrix(array)
print(b)
res = [] #indexes to remove
for i,m in enumerate(b):
if sum(m) > 1: #if the index IS a subset of any other index (excludes "True" identity of itself)
res.append(i)
return res
indexes_to_remove(a)
outputs >> [1,3,4,5]
My problem however, is that I need this function to work for a multidimensional array that is
[n X n X 2] whereas a is only [n X n X 1]. For example, I need it to work on something that looks like:
a = [array([[1,2],[1,5],[2,3],[5,7]]),
array([[2,3],[5,7]]),
array([[1,5],[4,5],[9,2]]),
array([[2,3],[4,5],[1,5]])]
which should return [1].
Please help! What change do I need to do to my function for it to work for a multidimensional array of this shape?
Related
I have [1,2,3] and I wish to get [(1,1,1), (1,4,9), (1, 8, 27)]. What is the easiest way to achieve this?
I'd probably do this with a list comprehension, an inner loop iterating over your array/list, i. e. [1,2,3] and an outer loop iterating over the powers , i. e. zero, one and two (EDIT: To achieve the output you specified in your question one would need [0,2,3] as powers list):
elements = [1,2,3]
powers = [0,1,2]
[[e**i for e in elements] for i in powers]
The output of this is
[[1, 1, 1], [1, 2, 3], [1, 4, 9]]
If you want a numpy array you can convert it with np.array() and if you want a list of tuples as you have it written in your question convert it with tuple(), i. e.
import numpy as np
elements = [1,2,3]
powers = [0,1,2]
# numpy array
np.array([[e**i for e in elements] for i in powers])
# list of tuples
[tuple([e**i for e in elements]) for i in powers]
I'd do it this way, check it out:
def get_cuadrado_cubo(lista):
resp = []
for i in range (4):
if i == 1:
continue
resp.append((lista [0] ** i, lista [1] ** i, lista [2] ** i) )
return resp
I want to create a function which gives me the corresponding position of the element in a given nested list:
nested_list = [[0,1,2], [4,5], [6,7,8,9], [10]]
So I want to be able to get a function that does this correspondence:
f(6)
#Here, nested_list[2][0] == 6
>> (2,0)
f(2)
#Here, nested_list[2][0] == 2
>> (0,2)
We get a tuple with the corresponding position of an element that is searched using the function.
My current solutions it is not very elegant neither very fast:
from itertools import accumulate
accum_len = list(accumulate([len(l) for l in nested_list]))
def getitem(nested_list, idx):
# first list case
if idx < len(nested_list[0]):
return 0, idx
# other ones in reverse order
for i, l in enumerate(accum_len[::-1]):
if idx >= l:
rel_idx = idx - l
return len(nested_list)-i, rel_idx
Assuming the list is not nested more than once, this should work:
nested_list = [[0,1,2], [4,5], [6,7,8,9], [10]]
def f(n):
return next((i,x.index(n)) for i,x in enumerate(nested_list) if n in x)
f(6)
# (2,0)
f(2)
# (0,2)
I have two lists
a = [1,2,3]
b = []
I want to move an element from list a, if it meets a certain condition.
a = [1,3]
b = [2]
The below code shows an example, however, I would like to do this inside of a single loop. How do I do this more efficiently?
a = [1,2,3]
b = []
pop_list = []
for i in range(len(a)):
if a[i] == 2:
print("pop:", a[i])
pop_list.append(i)
for i in range(len(pop_list)):
b.append(a.pop(pop_list[i]))
# Reset pop_list
pop_list=[]
Ideally, I would not generate a new list b.
A pair of list comprehensions would do the job: one to select the desired elements for b, the other to remove them from a
b = [i for i in a if i == 2]
a = [i for i in a if i != 2]
You can use filter and itertools.filterfalse and use the same filtering function for both:
from itertools import filterfalse
a = [1,2,3]
b = []
list(filterfalse(lambda x: x == 2, a))
list(filter (lambda x: x == 2, a))
[1, 3]
[2]
Here is the itertools.filterfalse docs.
If the element x exists you could just remove it from b and append it to a.
a = [1, 2, 3]
b = []
x = 2
def remove_append(a, b, x):
if x in a:
a.remove(x)
b.append(x)
remove_append(a, b, x)
print(a)
print(b)
Output:
[1, 3]
[2]
We must pass through all elements, however, you can apply this trick to add to the appropriate list in one loop:
(Appending to a loop is more efficient than deleting an element at arbitrary position)
a = [1,2,3]
condition_false, condition_true = [], []
for v in a:
# Add to the right list
(condition_false, condition_true)[v == 2].append(v)
# [1, 3]
print(condition_false)
# [2]
print(condition_true)
Here is a single loop way that's similar to your initial method:
length = len(a)
popped = 0
for i in range(length):
if i == length - popped:
break
if a[i] == 2:
b.append(a.pop(i))
popped += 1
If we keep track of how many elements we pop from a, we can just stop our loop that many elements early since there are fewer elements left in a.
I'm doing a code that needs to store the values of the inputs in two arrays. I'm gonna do a example.
INPUTS: 1,2,3,4,5,6,7,8
Array1= []
Array2= []
What I want to make is store the first value of the input in the array1 and the second in the array2. The final result will be this
Array1=[1,3,5,7]
Array2=[2,4,6,8]
Is possible to do that in python3? Thank you
I tried something like this but doesn't work
arr1,arr2 = list(map(int, input().split()))
You can use the following:
l = [int(x) for x in input().split(',')]
array_1 = l[::2]
array_2 = l[1::2]
So, I assume that you can get the inputs into a list or 'array' using the split? It would be nice to somehow 'map' the values, and numpy probably would offer a good solution. Though, here is a straight forward work;
while INPUTS:
ARRAY1.append(INPUTS.pop())
if INPUTS:
ARRAY2.append(INPUTS.pop())
your attempt:
arr1,arr2 = list(map(int, input().split()))
is trying to unpack evenly a list of 8 elements in 2 elements. Python can unpack 2 elements into 1 or 2, or even use iterable unpacking like:
>>> arr1,*arr2 = [1,2,3,4]
>>> arr2
[2, 3, 4]
but as you see the result isn't what you want.
Instead of unpacking, use a list of lists, and a modulo to compute the proper destination, in a loop:
lst = list(range(1,9)) # or list(map(int, input().split())) in interactive string mode
arrays = [[],[]]
for element in lst:
arrays[element%2].append(element)
result:
[[2, 4, 6, 8], [1, 3, 5, 7]]
(change the order with arrays[1-element%2])
The general case would be to yield the index depending on a condition:
arrays[0 if some_condition(element) else 1].append(element)
or with 2 list variables:
(array1 if some_condition(element) else array2).append(element)
There is my solution in a Class ;)
class AlternateList:
def __init__(self):
self._aList = [[],[]]
self._length = 0
def getItem(self, index):
listSelection = int(index) % 2
if listSelection == 0:
return self._aList[listSelection][int(index / 2)]
else:
return self._aList[listSelection][int((index -1) / 2)]
def append(self, item):
# select list (array) calculating the mod 2 of the actual length.
# This alternate between 0 and 1 depending if the length is even or odd
self._aList[int(self._length % 2)].append(item)
self._length += 1
def toList(self):
return self._aList
# add more methods like pop, slice, etc
How to use:
inputs = ['lemon', 'apple', 'banana', 'orange']
aList = AlternateList()
for i in inputs:
aList.append(i)
print(aList.toList()[0]) # prints -> ['lemon', 'banana']
print(aList.toList()[1]) # prints -> ['apple', 'orange']
print(aList.getItem(3)) # prints -> "orange" (it follow append order)
The pythonic way
Here I have taken some assumptions according to above question:
Given inputs only contain integers.
odd and even are two arrays which contain odd numbers and even numbers respectively.
odd, even = list(), list()
[even.append(i) if i % 2 == 0 else odd.append(i) for i in list(map(int, input().split()))]
print("Even: {}".format(even))
print("Odd: {}".format(odd))
I need to make a formula that, given two lists a and b, it returns the common elements in a and b. If the same element appears more than once in both, let's say xa times in a and xb times in b, then x should appear min(xa,xb) times in the results. If it's possible, don't use "import" in the code, please.
For example:
(Supposing my function is called common(a,b))
common([1,3,3,3],[1,3,3,3,3,4])
=> [1,3,3,3]
Thank you for your help!
A simple way is sort the two list first and compare the first element one by one. The code is like this:
def common(a, b):
sorted_a, sorted_b = sorted(a), sorted(b)
numa, numb = len(a), len(b)
rv = []
i, j = 0, 0
while i < numa and j < numb:
if sorted_a[i] == sorted_b[j]:
rv.append(sorted_a[i])
i += 1
j += 1
elif sorted_a[i] < sorted_b[j]:
i += 1
else:
j += 1
return rv
def common(lista=None,listb=None):
result_list=list()
inter_dict=dict()
lista_count=dict()
listb_count=dict()
for i in lista:
lista_count[i]=lista_count.get(i,0)+1 #convert lista to dict with frequency
for i in listb:
listb_count[i]=lista_count.get(i,0)+1 #convert listb to dict with frequency
for key in set(lista_count).intersection(set(listb_count)):
inter_dict[key]=min(lista_count[key],listb_count[key]) # get intersection of two dicts
for k,v in inter_dict.items():
result_list.extend([k]*v) #extend to the output list
return result_list
The output will give you when invoke the function common([1,3,3,3],[1,3,3,3,3,4]):
[1, 3, 3, 3]
def common(l1,l2):
totalElements = l1 + l2
resultList = []
for num in totalElements:
if num in l1 and num in l2:
resultList.append(num)
l1.remove(num)
l2.remove(num)
return resultList
l1 = [1,3,3,3,5]
l2 = [1,3,3,3,5,3,4]
result = common(l1 , l2)
print(result)
[1, 3, 3, 3, 5]
Three steps to resolve this problem:
Find out those elements should be in the final list, which is the intersection of two lists
For each element found in step #1, find out how many times it should be in final list
Generate final list based on the info found by previous two steps
And then translate these 3 steps to three lines of code:
def common(l1, l2):
intersection = [e for e in l1 if e in l2]
elemnts_counters = {e: min(l1.count(e), l2.count(e)) for e in intersection}
return sum([[e] * c for e, c in elemnts_counters.items()], [])
Then
print common([1,3,3,3], [1,3,3,3,3,4])
will give you:
[1, 3, 3, 3]