Remove all the elements before the given one from the array - python-3.x

Hi im trying to solve this question:
Not all of the elements are important. What you need to do here is to remove from the list all of the elements before the given one.
exemple:
remove_all_before([1, 2, 3, 4, 5], 3) == [3, 4, 5]
remove_all_before([1, 1, 2, 2, 3, 3], 2) == [2, 2, 3, 3]
remove_all_before([1, 1, 2, 4, 2, 3, 4], 2) == [2, 4, 2, 3, 4]
remove_all_before([1, 1, 5, 6, 7], 2) == [1, 1, 5, 6, 7]
remove_all_before([], 0) == []
remove_all_before([7, 7, 7, 7, 7, 7, 7, 7, 7], 7) == [7, 7, 7, 7, 7, 7, 7, 7, 7]
For the illustration we have a list [3, 4, 5] and we need to remove all elements that go before 3 - which is 1 and 2.
We have two edge cases here: (1) if a cutting element cannot be found, then the list shoudn't be changed. (2) if the list is empty, then it should remain empty.
def remove_all_before(items: list, border: int) -> Iterable:
limit = border
item_list = items
for i in item_list:
if i < limit:
return items[i+1:]
elif limit not in item_list:
return items
this is my code so far...and im stuck.
thanks for the help

this can be solved by using the index method of list and try and except command. here is the solution-
def remove_all_before(item, border):
try:
#search for the item
index = item.index(border)
print(f'the border is found at index {index}')
return item[index:]
except ValueError:
print('border not present')
return item

def remove_all_before(items: list, border: int) -> Iterable:
# your code here
for i in range(0, len(items)):
if (items[i] == border):
return items[i:]
return items

in my opinion this is the best solution, in this one you have the verification if border is in items
def remove_all_before(items, border):
result1 = []
result2 = []
for i in range(len(items)):
if (items[i] == border):
result1 = items[i:]
return result1
result2.append(items[i])
if (result1 == []):
return result2
else:
return result1

Related

How to append item to match the length of two list in Python

I am working on a Python script which is connected to a server. Every x min, server returns two list but the length of these list is not same. For ex:
a = [8, 10, 1, 34]
b = [4, 6, 8]
As you can see above that a is of length 4 and b is of length 3. Similarly, sometimes it returns
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
I have to write a logic where I have to check if length of these two list is not same, then add the 0 at the end of the list which is smaller than other list. So for ex, if input is:
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
then output will be:
a = [3, 6, 4, 5, 0, 0]
b = [8, 3, 5, 2, 9, 3]
What can I try to achieve this?
def pad(list1, list2):
# make copies of the existing lists so that original lists remain intact
list1_copy = list1.copy()
list2_copy = list2.copy()
len_list1 = len(list1_copy)
len_list2 = len(list2_copy)
# find the difference in the element count between the two lists
diff = abs(len_list1 - len_list2)
# add `diff` number of elements to the end of the list
if len_list1 < len_list2:
list1_copy += [0] * diff
elif len_list1 > len_list2:
list2_copy += [0] * diff
return list1_copy, list2_copy
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
# prints: ([3, 6, 4, 5, 0, 0], [8, 3, 5, 2, 9, 3])
print(pad(a, b))
a = [8, 10, 1, 34]
b = [4, 6, 8]
# prints: ([8, 10, 1, 34], [4, 6, 8, 0])
print(pad(a, b))
For now, I can suggest this solution:
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
# Gets the size of a and b.
sizeA, sizeB = len(a), len(b)
# Constructs the zeros...
zeros = [0 for _ in range(abs(sizeA-sizeB))]
# Determines whether a or b needs to be appended with 0,0,0,0...
if sizeA < sizeB:
a += zeros
else:
b += zeros
print(a,b)
You should use extend instead of append. This is the way to add a list to another list in Python. The list here is the list of zeros.
a = [3, 6, 4, 5, 9, 3]
b = [8, 3, 5, 2]
lenA, lenB = len(a), len(b)
diff=abs(len(a)-len(b))
if lenA < lenB:
a.extend([0]*diff)
else:
b.extend([0]*diff)
print(a)
print(b)
You could also try to use more_itertools padded() method:
It's prob. more elegant and adaptable for future Use cases.
Notes: just need to do pip install more_itertools first.
# simple example to demo it:
from more_itertools import padded
print(list(padded([1, 2, 3], 0, 5))) # last num: 5 is the numbers of 0 to be padded to make the total length to be 5. (needs 2 zeros)
# [1, 2, 3, 0, 0]
# more examples:
>>> L = [1, 2, 3]
>>> K = [3, 4, 5, 6, 8, 9]
>>> gap = len(K) - len(L)
# 3
# shorter list is L
>>>list(padded(L, 0, len(L) + gap))
[1, 2, 3, 0, 0, 0]

Cyclic Rotation of Numbers in a List in Python

I am trying to do cyclic rotation of numbers in List in Python.
For example,
An array A consisting of N integers is given. Rotation of the array means that each element is shifted right by one index, and the last element of the array is moved to the first place. For example, the rotation of array A = [3, 8, 9, 7, 6] is [6, 3, 8, 9, 7] (elements are shifted right by one index and 6 is moved to the first place).
The goal is to rotate array A K times; that is, each element of A will be shifted to the right K times.
For example, given
A = [3, 8, 9, 7, 6]
K = 3
the function should return [9, 7, 6, 3, 8]. Three rotations were made:
[3, 8, 9, 7, 6] -> [6, 3, 8, 9, 7]
[6, 3, 8, 9, 7] -> [7, 6, 3, 8, 9]
[7, 6, 3, 8, 9] -> [9, 7, 6, 3, 8]
I have written a function that is supposed to do the above task. Here is my code:
def sol(A, K):
for i in range(len(A)):
if (i+K) < len(A):
A[i+K] = A[i]
else:
A[i+K - len(A)] = A[i]
return A
A = [3, 8, 9, 7, 6]
K = 3
# call the function
sol(A,K)
[9, 3, 8, 3, 8]
I am getting [9, 3, 8, 3, 8] instead of [9, 7, 6, 3, 8].
Can anyone help me with the above code ?
Thanks.
Let's take a look at what happens if K = 1, on just the first iteration:
def sol(A, K):
for i in range(len(A)): # i = 0
if (i+K) < len(A): # i + 1 < 5
A[i+K] = A[i] # A[1] = A[0]
else:
A[i+K - len(A)] = A[i]
# A is now equal to [3, 3, 9, 7, 6] - the element at A[1] got overwritten
return A
The problem is that you don't have anywhere to store the elements you'd be overwriting, and you're overwriting them before rotating them. The ideal solution is to create a new list, populating it with rotated elements from the previous list, and return that. If you need to modify the old list, you can copy elements over from the new list:
def sol(A, K):
ret = []
for i in range(len(A)):
if (i + K) < len(A):
ret.append(A[i + K])
else:
ret.append(A[i + K - len(A)])
return ret
Or, more concisely (and probably how your instructor would prefer you solve it), using the modulo operator:
def sol(A, K):
return [
A[(i + K) % len(A)]
for i in range(len(A))
]
Arguably the most pythonic solution, though, is to concatenate two list slices, moving the part of the list after index K to the front:
def sol(A, K):
return A[K % len(A):] + A[:K % len(A)]

remove elements which are present in a list more than 2 times

I want to create a new list where each element can be present at max 2 times.
My code:
def valid_element(elements):
removed = 0
new_list = []
for i in elements:
if i not in new_list:
new_list.append(i)
else:
removed += 1
print(new_list)
print('Removed:', removed)
valid_element([1, 2, 3, 3, 3, 3, 4, 5, 8, 8])
The output I want:
Removed: 2
[1, 2, 3, 3, 4, 5, 8, 8]
You need to count unique elements in the list..
def valid_element(elements):
removed = 0
new_list = []
for i in elements:
if i not in new_list:
new_list.append(i)
elif i in new_list:
repeat_count = new_list.count(i)
if repeat_count < 2:
new_list.append(i)
else:
removed = i
print(new_list)
print('Removed:', removed)
valid_element([1, 2, 3, 3, 3, 3, 4, 5, 8, 8])
Output:
[1, 2, 3, 3, 4, 5, 8, 8]
Removed: 3
Your example shows items in sorted order. If duplicates are next to each other then you can do
from itertools import groupby, islice
alist = [1, 2, 3, 3, 3, 3, 4, 5, 8, 8]
result = [i for k, g in groupby(alist) for i in islice(g, 2)]
result contains
[1, 2, 3, 3, 4, 5, 8, 8]
If you need to know how many were removed you can do
num_removed = len(alist) - len(result)
If your original list is not in sorted order, and you don't mind reordering then do
result = [i for k, g in groupby(sorted(alist)) for i in islice(g, 2)]
Finally, here's a version that preserves order
from collections import Counter
c = Counter()
result = [i for i in alist if c.update([i]) or c[i] <= 2]

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]

How to remove Duplicate Values from a list in groovy

I have a collection of ID list to be saved into the database
if(!session.ids)
session.ids = []
session.ids.add(params.id)
and I found out that list has duplicates, like
[1, 2, 4, 9, 7, 10, 8, 6, 6, 5]
Then I wanted to remove all duplicates by applying something like :
session.ids.removeAll{ //some clousure case }
I found only this:
http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html
I am not a Groovy person , but I believe you can do something like this :
[1, 2, 4, 9, 7, 10, 8, 6, 6, 5].unique { a, b -> a <=> b }
Have you tried session.ids.unique() ?
How about:
session.ids = session.ids.unique( false )
Update
Differentiation between unique() and unique(false) : the second one does not modify the original list.
def originalList = [1, 2, 4, 9, 7, 10, 8, 6, 6, 5]
//Mutate the original list
def newUniqueList = originalList.unique()
assert newUniqueList == [1, 2, 4, 9, 7, 10, 8, 6, 5]
assert originalList == [1, 2, 4, 9, 7, 10, 8, 6, 5]
//Add duplicate items to the original list again
originalList << 2 << 4 << 10
// We added 2 to originalList, and they are in newUniqueList too! This is because
// they are the SAME list (we mutated the originalList, and set newUniqueList to
// represent the same object.
assert originalList == newUniqueList
//Do not mutate the original list
def secondUniqueList = originalList.unique( false )
assert secondUniqueList == [1, 2, 4, 9, 7, 10, 8, 6, 5]
assert originalList == [1, 2, 4, 9, 7, 10, 8, 6, 5, 2, 4, 10]
Use unique
def list = ["a", "b", "c", "a", "b", "c"]
println list.unique()
This will print
[a, b, c]
def unique = myList as Set
Converts myList to a Set. When you use complex (self-defined classes) make sure you have thought about implementing hashCode() and equals() correctly.
If it is intended that session.ids contain unique ids, then you could do:
if(!session.ids)
session.ids = [] as Set
Then when you do:
session.ids.add(params.id)
duplicates will not be added.
Also you can use this syntax:
session.ids << params.id
Merge two arrays and make elements unique:
def arr1 = [1,2,3,4]
def arr2 = [1,2,5,6,7,8]
def arr3 = [1,5,6,8,9]
Let's look at mergings:
arr1.addAll(arr2, arr3)
// [1, 2, 3, 4, [1, 2, 5, 6, 7, 8], [1, 5, 6, 8, 9]]
def combined = arr1.flatten()
// [1, 2, 3, 4, 1, 2, 5, 6, 7, 8, 1, 5, 6, 8, 9]
def combined = arr1.flatten().unique()
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
def combined = (arr1 + arr2 + arr3).flatten().unique()
def combined = (arr1 << arr2 << arr3).flatten().unique()
def combined = arr1.plus(arr2).plus(arr3).flatten().unique()
Output will be:
println combined
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Resources