Reputation: 774
The group
function picks up pp
from another big group. I want the program to say if any elements from pp
existed in rr
, I want to refuse it and call pick function again. If not append rr
list with pp
.
I have two lists like this:
rr = [[1,2], [3,4], [5,6], [7,8]]
pp = [[7,9], [10, 11]]
and I have this function:
for i in pp:
for j in i:
for k in rr:
for h in k:
while h == j:
pp = group(seq, 2)
else:
rr.append(pp)
Here rr
contains 7 which existed in pp
, must be refused. but the problem that it is still accepted. and rr
still appended by this wrong pp
.
If I do like this:
for i in pp:
for j in i:
for k in rr:
for h in k:
while h == j:
pp = group(seq, 2)
rr.append(pp)
else:
rr.append(pp)
It will still run forever without any output.
this is my soloution, it works, but i can't put it in answer:
rr1 = [[1,2], [3,4], [5,6], [7,8]]
pp1 = [[7,9], [10, 11]]
# if any(p in rr for p in pp):
# print("cant append") #this will send it back to the function to pick up new pp
# elif any((i in p for i in range(len(pp))) in (j in rr for j in range(len(rr))) for p in pp ):
# print("cant append")
# else:
# rr.extend(pp)
def is_true(pp , rr):
for i in pp:
for j in rr:
if any(p in j for p in i):
return False
return True
def ext (pp , rr , tt ):
if tt == True:
rr.extend(pp)
else:
print("cant append")
tt = is_true(pp1, rr1)
ext(pp1, rr1, tt)
print(rr1)
Upvotes: 0
Views: 1227
Reputation: 774
This is my solution, it works:
1- the group Function that choose the elements into groups:
import random
from students.models import students
pars = students.objects.all()
def groupp (x, y):
res = random.sample(x, y)
while len(set([u.first_language for u in res])) < y:
res = random.sample(x, y)
return res
2- the logic for accepting or Refusing that Group, then send the result to the view:
def lession_group (request):
results=[]
parr = list(students.objects.all())
pick = []
picked = []
final = []
for i in range(4):
pick = groupp (parr, 2)
while pick in final or pick[::-1] in final or any(p in picked for p in pick):
pick = groupp (parr, 2)
final.append(pick)
picked.extend(pick)
Upvotes: 0
Reputation: 10080
I think I know what you are asking, but I'm not sure. Because the question is phrased awkwardly, for me anyway.
I think you want to use sets. Sets are a data-structure in python that control lists of unique elements. So it sounds like you want things in rr only to be in rr, if they are not already in pp?
So, I'd use a set for pp. Create a set of everything in pp:
from itertools import chain
rr = []
pp = [[7,9], [10, 11]]
# create a unique set of elements from the lists in pp
unique_items_in_pp = set(chain(*pp))
def in_pp(items):
"""Takes an iterable, returns bool, True if an element of iterable is in pp"""
return set(items).isdisjoint(unique_items_in_pp)
# reject anything into rr if in the set
print(list(filter(rr_add, [[1,2], [3,4], [5,6], [7,8]])))
Running this code:
>>>[[1, 2], [3, 4], [5, 6]]
Because I find the question a bit awkward, I've just thrown together a possible solution. It's not complete, but hopefully it shows the main benefit of using a set
Upvotes: 1
Reputation: 1510
I approached this way:
def test_element_existed(list1, list2):
a = set([j for i in range(len(list1)) for j in list1[i]])
b = set([j for i in range(len(list2)) for j in list2[i]])
#check if any element in set(a) and set(b) are common and print it
print(bool(set(a) & set(b)), set(a) & set(b))
return list(a.union(b) - a.intersection(b))
test_element_existed(rr, pp)
result:
True {7}
[1, 2, 3, 4, 5, 6, 8, 9, 10, 11]
Upvotes: 1
Reputation:
Here another approach [Disclaimer: As the others I'm not entirely sure I understood your question correctly, please leave a comment if it is not what you want].
If any value in rr
appears in pp
,too, pp
will not be appended, else pp
will be appended.
rr = [[1,2], [3,4], [5,6], [7,8]]
pp = [[7,9], [10, 11]]
do_append = 1
for rr_sublist in rr:
for j in range(len(rr_sublist)):
for pp_sublist in pp:
for i in range(len(pp_sublist)):
if pp_sublist[i] == rr_sublist[j]:
print("duplicate element found")
do_append = 0
if do_append:
rr.append(pp)
print(rr)
Output:
duplicate element found
[[1, 2], [3, 4], [5, 6], [7, 8]]
Upvotes: 1
Reputation: 3758
If you are checkin single integers from both lists of lists, you can do something like:
from itertools import chain
def are_common_elements(rr, qq):
return bool(set(chain(*rr)) & set(chain(*qq)))
Upvotes: 3
Reputation: 23480
I'm not entirely sure what you're after.
But maybe this is something that you can work with:
import itertools
rr = [[1,2], [3,4], [5,6], [7,8]]
pp = [[7,9], [10, 11]]
result = []
ignore = []
for item in itertools.chain.from_iterable(pp):
for pair in rr:
if item in pair:
print('Yepp, {} is in {}. Ignoring!'.format(item, pair))
ignore.append(pair)
elif not pair in result and pair not in ignore:
result.append(pair)
print('Result: {}'.format(result))
itertools just flattens the "check list", so it's easier to work with the numbers. Then simply iterate over those and check which rr
pairs contain invalid numbers. Store those invalid pairs in ignore
.
If you don't want to ignore a pair, simply skip the ignore part.
But it will make sure that [7, 8]
doesn't belong in your results - if for instance your pp
looked like this: pp = [[7,9], [8, 11]]
Upvotes: 1