1

I'm stuck with comparing two lists and finding how many elements are <= list1 (list2 <= list1) and putting the result in a new_list.

Here are the test cases:

Test Case 1:

list1 = [1, 4, 2, 4]
list2 = [3, 5]
Output: [2, 4]

Explanation:

  1. For list2[0] = 3, we have 2 elements in list1 (list1[0] = 1 and list1[2] = 2) that are <= list2[0].

  2. For list2[1] = 5, we have 4 elements in list1 (list1[0] = 1, list1[1] = 4, list1[2] = 2, and list1[3] = 4) that are <= list2[1]

Test Case 2:

list1 = [1, 2, 3]
list2 = [2, 4]
Output: [2, 3]

Explanation:

  1. For list2[0] = 2, we have 2 elements in list1 (list1[0] = 1 and list1[1] = 2) that are <= list2[0].

  2. For list2[1] = 4, we have 3 elements in list1 (list1[0] = 1, list1[1] = 2, list1[2] = 3) that are <= list2[1]

I was thinking to solve with two pointers where I place the first pointer in list1[0] and 2nd pointer in list2[0] then compare each element in both lists and increment a count each time I see an element in list2 is smaller than elements in list1. The implementation is a little challenging to me and I'm sure whether it's working or not.

Here what I wrote:

def counts(list1, list2):
   new_list = []
   count = 0
   a = list1[0]
   b = list2[0]
   i, j = 1, 1

   while a or b:
     if a <= b:
        count += 1
        new_list.append(a[i])
        i += 1

   return new_list
Mo Fatah
  • 159
  • 1
  • 11

3 Answers3

2

You can use Python sum on boolean to get the number of items that match, e.g.

[sum(l1x <= l2x for l1x in list1) for l2x in list2]

If you need efficiency1, you can switch to a numpy based solution, such as

np.sum(np.asarray(list1)[:, None] <= [list2], axis=0)

If you want the version without list comprehension or without sum:

res = []
for l2x in list2:
    cnt = 0
    for l1x in list1:
        cnt += l1x <= l2x
    res.append(cnt)

1 Disclaimer: I did not test the actual efficiency.

Holt
  • 36,600
  • 7
  • 92
  • 139
  • Great! this is a simple working solution. But can we not use any Python built-in or import a package. I would say just pure python list manipulation or dictionary solution. Thanks though. – Mo Fatah Apr 20 '22 at 13:20
  • 1
    @MoFatah The first solution in my answer is pure Python without any library. I don't really see a point in not using Python built-ins... I can understand not wanting to pull a library for such small things if you do not already use it, but `sum()` is a Python built-in so there is no reason not to use it, unless you're doing some kind of programming exercises. – Holt Apr 20 '22 at 13:21
  • Correct! It's Python's list comprehension -- it looks like two nested loops to me (not an optimal solution, right?). Sorry, I'm not good at Python list comprehension, could you please convert it without list comprehension so I can see if it's nested loop? Thanks. – Mo Fatah Apr 20 '22 at 13:26
  • 1
    @MoFatah Yes, it's too nested loop - You cannot do better than two nested loops unless you accept to use more memory to store intermediate result. I've added the "simple" version to the answer but it's not pythonic at all. If you intend to use Python, you should learn how to work with list comprehension and the many built-ins (including the standard library). – Holt Apr 20 '22 at 13:45
  • thanks I now see what going on. Appreciate it. – Mo Fatah Apr 20 '22 at 13:49
1

The easiest way is:

import numpy as np
[(np.array(list1)<=l2).sum() for l2 in list2]

But if you need a more efficient solution, just let me know

1

You could sort both the input lists. Then binary search(bisect.bisect_right from std lib) to get the insertion position of values in list2 in list1. The position would eventually tell you how many values are less than the value of the items in list2.

from bisect import bisect_right # For binary search.

srt_l1 = sorted(list1) # NlogN
srt_l2 = sorted(list2) # MlogM

out = [bisect_right(srt_l1, val) for val in srt_l2] # MlogN

This brings the time complexity to O(NlogN + MlogM) with extra space of N+M(though you could sort in-place using list.sort). The suggested answers above have a time complexity of O(N*M).

Ch3steR
  • 20,090
  • 4
  • 28
  • 58
  • Indeed NlogN is better than N^2 but what if the interviewer tells you, Hey, don't use built-in or import any library? – Mo Fatah Apr 20 '22 at 14:01
  • You could easily write a binary search, which is what `bisect_right` is. – Ch3steR Apr 20 '22 at 14:02
  • Would be nice if you implement it with this problem if you have some time, please. – Mo Fatah Apr 20 '22 at 14:05
  • 1
    @MoFatah I'll write up when I find some time. You can refer to the algorithm [here](https://stackoverflow.com/a/13307803) though written in ruby but could easily be translated into python. – Ch3steR Apr 20 '22 at 14:12