6

How can i check if item in b is in a and the found match item in a should not be use in the next matching?

Currently this code will match both 2 in b.

a = [3,2,5,4]
b = [2,4,2]

for i in b:
  if i in a:
    print "%d is in a" % i

This is the required output:

2 => 2 is in a
4 => 4 is in a
2 =>

EDIT: Example 2:

a = [3,2,2,4]
b = [2,4,2]

output should be

2 => 2 is in a
4 => 4 is in a
2 => 2 is in a
0

5 Answers 5

11

(long post but read it entirely, solution is at the end).

Remove the found value or register it in another dict.

Better though is to count the number of apparitions inside each array and test how many are common.

For the second case, you'd have

  • for a:

    3 appears 1 times 2 appears 1 times 5 appears 1 times 4 appears 1 times

  • for b:

    2 appears 2 times 4 appears 1 times

Keep these values in dictionaries:

a_app = {3:1, 2:1, 5:1, 4:1}
b_app = {2:2, 4:1}

And now, it is simple:

for i in b:
    if a_app.has_key(i) and a_app[i] > 0:
        a_app[i] -= 1

The b_app dictionary would be used in other case.

Here is a test script I wrote (testing all testcases issued here):

def f(a, b):
    a_app = {}
    for i in a:
        if not a_app.has_key(i):
            a_app[i] = 0
        a_app[i] += 1
    print a_app
    for i in b:
        print i, '=>',
        if a_app.has_key(i) and a_app[i] > 0:
            a_app[i] -= 1
            print i, ' is in a',
        print '.'

f([1,1,2],[1,1])
f([3,2,5,4],[2,4,2])
f([3,2,2,4],[2,4,2])
f([3,2,5,4],[2,3,2])

And here is the output:

$ python 1.py
{1: 2, 2: 1}
1 => 1  is in a .
1 => 1  is in a .
{2: 1, 3: 1, 4: 1, 5: 1}
2 => 2  is in a .
4 => 4  is in a .
2 => .
{2: 2, 3: 1, 4: 1}
2 => 2  is in a .
4 => 4  is in a .
2 => 2  is in a .
{2: 1, 3: 1, 4: 1, 5: 1}
2 => 2  is in a .
3 => 3  is in a .
2 => .

Everything is perfect and no order is lost :)

Edit: Updated with @Avaris's suggestions, this script looks like:

import collections

def f(a, b):
    a_app = collections.Counter(a)
    for i in b:
        print i, '=>',
        if i in a_app and a_app[i] > 0:
            a_app[i] -= 1
            print i, ' is in a',
        print '.'
    print ''

f([1,1,2],[1,1])
f([3,2,5,4],[2,4,2])
f([3,2,2,4],[2,4,2])
f([3,2,5,4],[2,3,2])
Sign up to request clarification or add additional context in comments.

4 Comments

Nice but loses order of the values found - not sure if that is important.
Nop, it doesn't loose anything :) See output from tests.
You should use i in a_app instead of a_app.has_key(i). has_key is removed in 3.x. And for 2.7+ collections.Counter will do nicely for a_app or b_app.
collections.Counter is available to python v2.7 up.
3

I would do this:

a = [3,2,5,4]
b = [2,4,2]
temp = set(a)
for item in b:
    if item in temp:
        print "{0} is in a".format(item)
        temp.remove(item)

The set makes the x in y check faster (O(1) instead of (worst-case) O(n)), and it also can be modified safely without destroying my original a.

9 Comments

fails with a = [1,1,2], b = [1,1]
@MariaZverina: How do you mean? Output is 1 is in a - what else would you have expected?
set will modify the value of a. When my variable a=[3,2,2,4] both 2 in b should match.
@Bob: Then you should edit your question to specify your problem correctly. set() does not modify the value of a, by the way.
He stated it clearly: he wanted to match each value exactly once even though he had duplicates.
|
3

Recursive solution:

a = [3,2,5,4]
b = [2,4,2]

def find_matches(x, y):
    if y == []:            # nothing more to find
        return
    n = y.pop()
    if n in x:
        print n, "matches"
        x.remove(n)
    find_matches(x, y)

find_matches(list(a), list(b))      # copy the list as they get consumed in process

Comments

0
a = [3,2,5,4]
b = [2,4,2]

hadAlready = {}
for i in b:
    if i in a:
        if not (i in hadAlready):
            print "%d is in a" % i
            hadAlready[i] = 1

1 Comment

fails with a = [1,1,2], b = [1,1]
0

This probably isn't the best way to do it, but you could make a list of all matched items and check using that.

a= [3, 2, 5, 4]
b= [2, 4, 2]
c= []

for i in b:
    if i in a and i not in c:
        print '%d is in a' % i
        c.append(i)

I think looping over a instead of b should solve the problem.

a= [3, 2, 2, 4]
b= [2, 4, 2]

for i in a:
    if i in b:
        print i, 'is in a'

Obviously i is in a, but it does solve the problem doesn't it?

7 Comments

fails with a = [1,1,2], b = [1,1]
Fails? How? It gives the output 1 is an a And that is the required output
The output should be given twice, you have two 1s in b.
Ah, got it. The OP should edit the question to make that clear.
@elssar yes, already edited. My first example is not that appropriate
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.