Removing list elements that repeats itself- python - python

I have an array that looks like
A=[0,0,1,1,2,5,6,3,7,7,0,0,1,1,2,5,6,3,7,7]
since the "0,0,1,1,2,5,6,3,7,7" part reapeats itself I dont need the second part so for a given array it should give me
A=[0,0,1,1,2,5,6,3,7,7]
I cant use the set() function and I dont know what else I can use in this case.Is there a function which can do this operation ?

I defined the following two methods:
def check_repeat(l):
for i in range(1,len(l)//2+1):
pattern=l[:i]
sub_lists=create_sublists(l, i, True)
if all([x==pattern for x in sub_lists]):
print("Found pattern {} with length {}".format(pattern, i))
return pattern
def create_sublists(l, n, only_full=False):
sub_lists=[]
for j in range(n, len(l),n):
if only_full and len(l[j:j+n])<n:
continue
sub_lists.append(l[j:j+n])
return sub_lists
It works as follows: with check_repeat(your_list) the input list is checked for patterns of arbitrary length. A pattern of length i is found, if the first i entries of your_list equal all following sub_lists of length i. The sublists are created by the method create_sublists, which returns a list of lists. If only_full is set to True, only sublists with length n are allowed. This handles the case where your list looks for example like this A=[1,2,3,1,2,3,1,2] and you want to accept [1,2,3] as a valid pattern and ignore the remaining sublist [1,2].
Each sublist is then compared to the current pattern, i.e. the first i entries of your input list. If all sublists, equal the current pattern, a true pattern is found.
In contrast to the solution in Python finding repeating sequence in list of integers?, I do not only check the next i entries if they match the current pattern, but all of the following sublists with length i.

Edit: Oooops, didn't see that you don't want to use a set. NVM, sorry.
What I would recommend doing is converting your list to a set and then back, like this:
A=[0,0,1,1,2,5,6,3,7,7,0,0,1,1,2,5,6,3,7,7]
S = set(A)
If you want to do it iteratively (, because you might want to add an extra condition):
S = set()
for item in A:
s.add(item)
And then you can convert the set back to a list like this:
A = list(S)
print(A)
>>A=[0,0,1,1,2,5,6,3,7,7]

Related

How can I sum pairs of numbers in a list and if the sum is equal to another element in the list, how can I remove this element from the list?

I have a list of numbers:
nums = [-3,-2,-1,1,2,3,0,0]
And I want to iterate over the list, and add two numbers at a time, and if the sum of these two numbers is an element in the list (excluding the two we just summed), then I want to remove the element. How can I do this?
For example, since -3+2= -1 and -1 is in the list, I can remove -1 from the list.
I tried to create an empty list/set to store the sums of each pair of elements, then compare the elements in nums to this list/set, but this doesn't work, as it violates the second part of what I want to do- in brackets above!
P.S. I would like to remove as many elements as possible, and one worry is that if I remove elements as I iterate the list- before finding all of the pair sums- then I might miss some valid pair sums!
Any help is much appreciated.
Although possibly inefficient (didn't care about efficiency when writing this answer), you could probably do the following:
for first in nums[:]:
if first == 0: continue
for second in nums[:]:
if second == 0: continue
sum = first + second
if sum in nums:
nums.remove(sum)
There are 2 things I will go over in this answer;
nums[:] is the slicing syntax that will just create a copy of the array, whereafter that copy will be iterated over. The syntax for this was found within this answer: https://stackoverflow.com/a/1207461/6586516
There are also checks to see if either the first or second number is equal to 0. This will satisfy the second condition (according to my logic). The only time the sum of a set of numbers can be equal to itself/one of the numbers used in the addition is when n - 1 numbers is equal to 0 (where n is the amount of numbers used in the addition)
You could try something like this:
itertools.combinations returns us with all possible combinations of a the argument. Since you want to numbers, providing 2 as the argument will return all possible combinations with length 2
Then we will just check the conditions and proceed to remove from the list.
from itertools import combinations
nums = [-3,-2,-1,1,2,3,0,0]
nums2=[i for i in combinations(nums,2)]
print(nums2)
for i in nums2:
sums=i[0]+i[1]
if sums in nums and (sums!=i[0] and sums!=i[1]):
try:
print(f"{sums} removed from list.\nNew List: {nums}")
nums.remove(sums)
except ValueError:
print("{sums} not in list")
print(nums)

Find matching elements of two unordered Python lists of different sizes

I'm getting this error: index out of range, in if largerList[j] == smallerList[i]. I'm working on an assignment about binary search trees, I put the trees into lists and I'm just trying to compare the two lists:
def matchList(largerList, smallerList) :
matches = []
for i in smallerList:
for j in largerList:
if largerList[j] == smallerList[i] :
matches[i] = smallerList[i]
return matches
I'm assuming nested for loops should totally iterate all elements in each loop, so smallerList is the smaller list so smallerList doesn't make largerList go out of bounds. The inner for-loop should iterate over all of the larger list entirely, comparing each value to each element of the smaller list. Why doesn't it work?
You can't set a list value with matches[i] if that index does not exist in matches.
Try appending instead:
Change this matches[i] = smallerList[i] to this matches = matches.append(smallerList[i])
Trying to find matching elements in lists like this is rather inefficient. One thing you could improve to make it arguably more pythonic is to use a list comprehension:
matches = [i for i in largerList if i in smallerList]
But then the more mathematically sensible approach still would be to realise that we have two sets of elements and we want to find an intersection of two sets so we can write something like:
matches = set(largerList).intersection(smallerList)

How to check list for double elements and then delete both elements in Python 2

I have a list of elements which I'd like to check for double elements (no element will be there 3 times, just once or twice) and then I'd like to remove the original and the copy of such an element. So in the end I need a list that contains all elements which have only been present once in the original list.
The elements of the list are lines so I need to check both, end and start point against each other to see, which lines are the same. I already wrote some lines of which none seemed to work. I have already written a small function that checks the lines and finds doublets but I can't seem to work out how to delete both the copy and the original element in my list. This is the function that finds double lines:
def cmp_lines(l1, l2):
return(l1[0]==l2[0] and l1[1]==l2[1]) or (l1[0]==l2[1] and l1[1]==l2[0])
an example would be something like this:
list = [Line([1,0],[2,1]), Line([1,3],[4,5]), Line([2,1],[1,0])]
newList = [Line([1,3],[4,5])]
Using Python 2.x is a requirement.
you should write a function which takes as input the list of lines and filter it accordingly. That function will use cmp_lines to compare if two lines are equals.
Adapt the following method according to your objects and classes definitions.
def filter_lines(lst) : # lst is the list of lines to filter
for i in range(len(lst)) :
is_unique = True
for j in range(i+1,len(lst)) :
if cmp_lines(lst[i],lst[j]) :
lst.pop(j) #remove the lst[j] from the list
is_unique = False #a same line was found
break;
if not is_unique : #The line lst[i] is unique
lst.pop(i) #remove lst[i] from the list
return lst

Python: Compare first n characters of item in list to first n characters of all other items in same list

I need to compare the first n characters of items in a list to the first n characters of other items in the same list, then remove or keep one of those items.
In the example list below, “AB2222_100” and “AB2222_P100” would be considered duplicates (even though they're technically unique) because the first 6 characters match. When comparing the two values, if x[-4:] = "P100", then that value would be kept in the list and the value without the “P” would be removed. The other items in the list would be kept since there isn’t a duplicate, regardless of whether it's “P100” or “100” suffix at the end of the string. For this case, there will never be more than one duplicate (either a “P” or not).
AB1111_100
AB2222_100
AB2222_P100
AB3333_P100
AB4444_100
AB5555_P100
I understand slicing and comparing, but everything is assuming unique values. I was hoping to use list comprehension instead of a long for loop, but also want to understand what I'm seeing. I've gotten lost trying to figure out collections, sets, zip, etc. for this non-unique scenario.
Slicing and comparing isn't going to retain the required suffix that needs to be maintained in the final list.
newList = [x[:6] for x in myList]
This is how it should start and end.
myList = ['ABC1111_P100', 'ABC2222_100', 'ABC2222_P100', 'ABC3333_P100', 'ABC4444_100', 'ABC5555_P100']
newList = ['ABC1111_P100', 'ABC2222_P100', 'ABC3333_P100', 'ABC4444_100', 'ABC5555_P100']
As stated in your comments you can't do this in a one liner. You can do this in O(n) time but it will take some extra space:
myList = ['ABC1111_P100', 'ABC2222_100', 'ABC2222_P100', 'ABC3333_P100', 'ABC4444_100', 'ABC5555_P100']
seen = dict()
print(myList)
for x in myList:
# grab the start and end of the string
start, end = x.split('_')
if start in seen: # If we have seen this value before
if seen[start] != 'P100': # Did that ending have a P value?
seen[start] = end # If not swap out the P value
else:
# If we have not seen this before then add it to our dict.
seen[start] = end
final_list = ["{}_{}".format(key, value) for key, value in seen.items()]
print(final_list)

Sorting out unique elements from a list to a set

I was writing a function to save unique values returned by a list "list_accepted_car" to a set "unique_accepted_ant". list_car_id is list with the value ['12','18','3','7']. When i run the code i am getting error , "unhashable list ". Can anyone suggest me what is the error?
list_accepted_car = [] #set to store the value list_accepted_car
unique_accepted_car = set() #set to store the value unique_accepted_car
num_accepted = 2 #predifined value for the number of cars allowed to enter
def DoIOpenTheDoor(list_car_id): #list_ant_id is a list of cars allowed to enter
if len(list_accepted_car) < num_accepted:
if len(list_car_id) > 0:
list_accepted_car.append(list_car_id[0:min(len(list_car_id),num_accepted-len(list_accepted_car))])
unique_accepted_list = set(list_accepted_car)
print unique_accepted_list
return list_accepted_car
Under the assumption that list_car_id looks like: [1,2,3,4,5].
You add in list_accepted_car a sublist of list_car_id, so list_accepted_car will look like [[1,2]] i.e. a list of a list.
Then you should change
unique_accepted_list = set(list_accepted_car)
to
unique_accepted_list = set([x for y in list_accepted_car for x in y])
which will extract each element of the sublist and provide a flatten list. (There exists other options to flatten a list of list)
You are saving a list of lists, which can't be converted to a set. You have to flatten it first. There are many examples of how to do it (I'll supply one using itertools.chain which I prefer to python's nested comprehension).
Also, as a side note, I'd make this line more readable by separating to several lines:
list_accepted_car.append(list_car_id[0:min(len(list_car_id),num_accepted-len(list_accepted_car))])
You can do:
from itertools import chain
# code ...
unique_accepted_list = set(chain.from_iterable(list_accepted_car))
The best option would be to not use a list at all here, and use a set from the start.
Lists are not hashable objects, and only hashable objects can be members of sets. So, you can't have a set of lists. This instruction:
list_accepted_car.append(list_car_id[0:min(len(list_car_id),num_accepted-len(list_accepted_car))])
appends a slice of list_car_id to list_accepted_car, and a slice of a list is a list. So in effect list_accepted_car becomes a list of lists, and that's why converting it to a set:
unique_accepted_list = set(list_accepted_car)
fails. Maybe what you wanted is extend rather than append? I can't say, because I don't know what you wanted to achieve.

Categories