Ahmad Ali
Ahmad Ali

Reputation: 774

Check if an element existed in a list of lists

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

Answers (6)

Ahmad Ali
Ahmad Ali

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

Donal
Donal

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

hemanta
hemanta

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

user10835998
user10835998

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

Aaron_ab
Aaron_ab

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

Torxed
Torxed

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

Related Questions