-2

How could I check if an element of a list is in a second list, but if the element of the first list has another same value (appears multiple times), the second list needs to have another too (needs to have multiple instances too).

I will show my code and output to demonstrate what I want it to be.

Input:

List_1 = [1, 2, 2]
List_2 = [1, 2, 2, 3, 4]

print("First list is", List_1)
print("Second list is", List_2)

res = all(ele in List_2 for ele in List_1)

print(f"Output: {res}")

Output:

First list is [1, 2, 2]
Second list is [1, 2, 2, 3, 4]
Output: True

As you can see, if element of a first list has another same value, second list needs to have it too.

But if second list doesn't have another value, I want it to be false.

This is an example.

Input:

List_1 = [1, 2]
List_2 = [1, 2, 2, 3, 4]

print("First list is", List_1)
print("Second list is", List_2)

res = all(ele in List_2 for ele in List_1)

print(f"Output: {res}")

My desired output is:

First list is [1, 2]
Second list is [1, 2, 2, 3, 4]
Output: False

This is the output that I want. How could I fix my code?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Arnu C.
  • 19
  • 7
  • 2
    I'm not sure why should the first example return True and the second return False, could you elaborate a bit more? – Gugu72 Aug 29 '23 at 14:37
  • @Gugu72, The second it is actually return True, but I want it to be false. So I want to know how to change my code to return false, because the first list has 2 only 1 integer but second list has 2 for 2 integer. Sorry for my english is bad. – Arnu C. Aug 29 '23 at 14:47
  • For the title, I think what you want is "Check that all elements of a list are in another list in the same number" or "amount" – wjandrea Aug 29 '23 at 15:02
  • 2
    I changed the problem's description to what I understand it should say. But it was not clear. Should the number of repetitions of each element be exactly the same, or greater or same, or maybe it doesn't matter as long as it's more than one? What should happen for lists [1, 2, 2] and [1, 2, 2, 2, 3]? What should happen for lists [1, 2, 2, 2, 2, 2] and [1, 2, 2]? – anatolyg Aug 29 '23 at 15:04
  • 1
    *"but if the element of the first list has another same value (EDIT: appears multiple times), the second list needs to have another too"*: It seems this is the opposite of what you show in the examples. I believe "first" and "second" should be swapped in that phrase to have it describe the same thing as in the examples. And maybe you want to require **both**: if both lists include the same value, that value should appear the same number of times in both lists. – trincot Aug 29 '23 at 15:14
  • Related? [How to efficiently compare two unordered lists (not sets)?](/q/7828867/4518341) – wjandrea Aug 29 '23 at 15:18
  • Great example how the requirements can result wrong implementation :-). Sorry for this comment. – Hermann12 Aug 29 '23 at 15:48

4 Answers4

4

It seems you want to only return True when the first list has only values that occur in the second, and when a value does occur in the first list, it should occur an equal number of times in both lists.

You can use Counter for that:

from collections import Counter
c1 = Counter(List_1)
c2 = Counter(List_2)
res = not (c1 - c2) and len(c2 - c1) == len(c2) - len(c1)

Tests:

from collections import Counter

def validate(lst1, lst2):
    c1 = Counter(lst1)
    c2 = Counter(lst2)
    return not (c1 - c2) and len(c2 - c1) == len(c2) - len(c1)
    
List_1 = [1]
List_2 = [1, 2, 2, 3, 4]

for i in range(4):
    print(List_1, List_2, validate(List_1, List_2))
    List_1.append(2)  # Each iteration add one more 2 in the first list

Output:

[1] [1, 2, 2, 3, 4] True
[1, 2] [1, 2, 2, 3, 4] False
[1, 2, 2] [1, 2, 2, 3, 4] True
[1, 2, 2, 2] [1, 2, 2, 3, 4] False
trincot
  • 317,000
  • 35
  • 244
  • 286
2

Use the built-in count method of lists:

List_1 = [1, 2]
List_2 = [1, 2, 2, 3, 4]

print("First list is", List_1)
print("Second list is", List_2)

res = all(
    List_1.count(ele) == List_2.count(ele)
    for ele in List_1
)

print(f"Output: {res}")

which gives as result:

First list is [1, 2]
Second list is [1, 2, 2, 3, 4]
Output: False
Xukrao
  • 8,003
  • 5
  • 26
  • 52
  • 2
    This will work, but it's inefficient; *O(n^2)*, I believe. You only need to do the counts once, which is *O(n)*. For example use a `Counter` like in [trincot's answer](/a/77001282/4518341). – wjandrea Aug 29 '23 at 15:10
1

As far as I understand, you need to test if cardinality of all List_1 elements are exactly the same as in List_2. If this is the case, the following one-liner should provide the expected results:

from collections import Counter
from functools import partial
from operator import contains

List_1 = [1, 2]
List_2 = [1, 2, 2, 3, 4]

Counter(List_1) == Counter(filter(partial(contains, {*List_1}), List_2))
0

You can remove the element that's present on each iteration like so

list_2_copy = list_2.copy() # to avoid changing the original list
result = False
for elem_1 in list_1:
    if elem_1 in list_2_copy:
        # by removing each time you're sure you have the right amount 
        list_2_copy.remove(elem_1) 
        result = True
    else: 
        result = False
        break
Ant0ine64
  • 177
  • 1
  • 12