5

如何检查项目b是否在中,a并且找到的匹配项目a不应在下一次匹配中使用?

目前,此代码将匹配 2 中的b.

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

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

这是所需的输出:

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

编辑:示例 2:

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

输出应该是

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

5 回答 5

11

(长篇但完整阅读,解决方案在最后)。

删除找到的值或将其注册到另一个字典中。

更好的方法是计算每个数组中的幻影数量并测试有多少是常见的。

对于第二种情况,你会有

  • 对于a

    3 出现 1 次 2 出现 1 次 5 出现 1 次 4 出现 1 次

  • 对于b

    2 出现 2 次 4 出现 1 次

将这些值保存在字典中:

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

现在,很简单:

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

字典将b_app在其他情况下使用。

这是我编写的测试脚本(测试此处发布的所有测试用例):

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])

这是输出:

$ 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 => .

一切都很完美,没有订单丢失:)

编辑:用@Avaris 的建议更新,这个脚本看起来像:

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])
于 2012-07-11T10:47:12.423 回答
3

我会这样做:

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)

该设置使x in y检查更快(O(1)而不是(最坏情况)O(n)),并且还可以安全地修改它而不会破坏我原来a的 .

于 2012-07-11T10:42:53.827 回答
3

递归解决方案:

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
于 2012-07-11T10:45:51.910 回答
0

这可能不是最好的方法,但您可以列出所有匹配的项目并使用它进行检查。

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)

我认为循环 a 而不是 b 应该可以解决问题。

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

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

显然i是 in a,但它确实解决了问题,不是吗?

于 2012-07-11T10:44:10.353 回答
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
于 2012-07-11T10:44:50.120 回答