I want to compare sublist I get from a list, if the numbers of the sublist are the same return True, like this:
list([[2,1,1,6],[6,2,1],[2,2,6,1],[2,1,6]])
True
but if it haven't the same numbers in the sublist return False
list([[2,1,1,6],[2,8,6,1],[2,1,6]])
False
Related
Say I have a list:
Os = [(4,P1),(9,P2),(4,P3),(1,P4),(9,P5)].
I want to put every second element of the tuple in a bag that has the same first element like this:
SortedOs = [(4,[P1,P3]),(9,[P2,P5]),(1,P4)].
Currently I'm using bagof/3:
findall(
(O,Bag),
bagof(P,member((O,P),Os),Bag),
SortedOs
).
But instead it gives me the sorted list like this:
SortedOs = [(1,P4),(4,[P1,P3]),(9,[P2,P5])]
Which means bagof/3 looks up the first element in ascending order. Is there any way I can change this to get the list I want? Many thanks.
If you are using SWI-Prolog and you can change the format of the data from tuples to Pairs, (Key-Value) then you can use group_pairs_by_key/2.
Note that for group_pairs_by_key/2 to work correctly the input list must be sorted.
Code
example(Pairs0,Result) :-
sort(Pairs0,Pairs1),
group_pairs_by_key(Pairs1,Result).
Example usage
?- Pairs = [4-P1,9-P2,4-P3,1-P4,9-P5],example(Pairs,Result).
Pairs = [4-P1, 9-P2, 4-P3, 1-P4, 9-P5],
Result = [1-[P4], 4-[P1, P3], 9-[P2, P5]].
SWI-Prolog has a library of predicates for working with ordered sets (sorted list). ordsets.pl -- Ordered set manipulation
Here is a variation that checks if the input is an ordered set and skips the sorting if it is an ordered set.
example(List,Result) :-
(
is_ordset(List)
->
Order_set = List
;
list_to_ord_set(List,Order_set)
),
group_pairs_by_key(Order_set,Result).
Example usage
?- List = [1-P4, 4-P1, 4-P3, 9-P2, 9-P5],example(List,Result).
List = [1-P4, 4-P1, 4-P3, 9-P2, 9-P5],
Result = [1-[P4], 4-[P1, P3], 9-[P2, P5]].
?- List = [4-P1,9-P2,4-P3,1-P4,9-P5],example(List,Result).
List = [4-P1, 9-P2, 4-P3, 1-P4, 9-P5],
Result = [1-[P4], 4-[P1, P3], 9-[P2, P5]].
Note: Ordered Sets remove duplicates so using list_to_ord_set/2 instead of sort/2 will remove duplicates.
?- List = [4-P1,4-P1,9-P2,4-P3,1-P4,9-P5],example(List,Result).
List = [4-P1, 4-P1, 9-P2, 4-P3, 1-P4, 9-P5],
Result = [1-[P4], 4-[P1, P3], 9-[P2, P5]].
group_pairs_by_key/2 (source code)
I want to create a predicate same_position(B,X,Y) that is true if element X and element Y have the same position within their respective nested lists.
For example,
same_position([[b,c,f],[a,d,g],[h,e]],c,d) would return true.
same_position(L,E1,E2):-
position(L,E1,N),
position(L,E2,N).
position(LL,E,N):-
member(L,LL),
nth0(N,L,E).
?- same_position([[b,c,f],[a,d,g],[h,e]],c,d).
true
?- same_position([[b,c,f],[a,d,g],[h,e]],b,N).
N = b ;
N = a ;
N = h ;
false.
So using the predicates from your other question this is pretty simple.
Here's my approach:
1. position predicate checks the positions of two elements.
2. It then compares the values.
position([H|T],Element1,Element2):-
checkElement([H|T],Element1,P1),
checkElement([H|T],Element2,P2),
P1=P2.
checkElement([],_,_).
checkElement([H|T],Element,P):-
( member(Element,H)->
nth0(P,H,Element);checkElement(T,Element,P)).
Example:-
?-position([[b,c,f],[a,d,g],[h,e]],b,g).
false
?-position([[b,c,f],[a,d,g],[h,e]],b,a).
true
false
I want to do this :
val list1 = List(Student("ivan","history",45))
val list2 = List(Student("ivan","history",40),Student("alexander","physics",81),Student("vlad","math",70))
I want to combine list1 and list2 so that list1's element remove list's 2 element based on student name and subject.
Required Output :
List(Student("ivan","history",45),Student("alexander","physics",81),Student("vlad","math",70))
I would go for a groupBy here. You concatenate the two lists, then you groupBy and take the head element for each key. This will scrumble the order among students though, but is efficient.
(list1 ++ list2)
.groupBy(s => (s.name, s.subject))
.map { case (key, values) =>
values.head
}
You can define a function to check if two Student values match:
def isSame(s: Student, t: Student): Boolean = (s.name == t.name && s.sub == t.sub)
Using this you can iterate over list2 and check if there is a match in list1. If there is, you use the value from list1 else keep the value from list2.
list2.map(s2 => (list1.map(s1 => if (isSame(s1, s2)) s1 else s2))).flatten
Note that this might not be the most optimal solution if the two lists are huge.
list1 = ['a','b','c','d']
list2 = ['b','c','d','a']
I have these two unordered lists and want to check if both have EXACTLY the same elements. Don't want to use set() or sorted() methods. But use looping to loop through both lists.
Keep it simple, without any helper function or list comprehension:
list1 = ['a','b','c','d']
list2 = ['b','c','d','a']
def same_lists(li1, li2):
if len(li1) != len(li2): # if the length of the lists is different than they are not equal so return false
return False
else:
for item1 in li1:
if item1 not in li2:
return False # if there is one item in li1 that is not in li2 than the lists are not identical so return false
for item2 in li2:
if item2 not in li1:
return False # same as three rows up
return True # if we didn't returned false for the whole list, than the lists are identical and we can return true.
print (same_lists(list1,list2))
This should work:
common_elements = [x for x in list1 if x in list2]
if len(list1) == len(list2) == len(common_elements):
print("EXACT SAME ELEMENTS")
else:
print("DIFFERENT ELEMENTS")
If you sort the elements first, or keep track as you encounter them, e.g. in another container, you can hand roll some solutions.
If you insist on avoiding this you need to check everything in the first list is in the seocnd and vice versa.
def same_lists(li1, li2):
if len(li1) != len(li2):
return False
else:
for item in li1:
if item not in li2:
return False
for item in li2:
if item not in li1:
return False
return True
This returns True for list1 = ['a','b','c','d'] compared with list2 = ['b','c','d','a'] and False for list3 = ['b','c','d','a', 'a'] and list4 = ['b','c','d','a', 'z'].
This is quadratic - we've compared everything with everything else (with a small optimisation checking the lengths first). We have to go through BOTH lists comaparing with the other list.
It would be quicker to sort first.
so imagine I had a sublist
exList = [
['green', 'apple', 'NO'],
['red','apple','nO'],
['red','watermellon','no'],
['yellow','honeymellon','yes']
]
so I want to check if the first value in the list is equal to the first value in the other list.
so exlist is a sublist, it has 4 different list. So i want to check the first value in the first list and check if it's equal to any other value in the other list. So Green is the first value and green is not used in the other list so it should return False. But if green was used in the other lists it should return True.
for i in exList:
if i+1[1] == i-[1]:
print True
how can i do this?
So if I understand your request you want to check if the first value for the first list in exList exists in each of the remaining lists? If so you could use list comprehension as follows:
check = [True if (exList[0][0] in subList) else False for subList in exList[1:]]
or you can do this in a loop if you don't understand list comprehension:
check = []
checkItem = exList[0][0] #Pulls the value for the first item in the first list of exList
for i in range(1,len(exList)): #Starts at 1 to skip the first list in exList
check.append(checkItem in exList[i])
print check
And if you need to loop over each item in the first list to check:
for eachListItem in exList[0]:
print "Search Text: %s" % (eachListItem)
curCheck = [True if (eachListItem in subList) else False for subList in exList[1:]]
print "Search Results: %s" % (True in curCheck)
Note: None of this would account for spaces in a string or mismatched cases (I.E. NO and No are two different values and would return false. Similarly "No " and "No" are different)