Python: Intersecting Two List Lists

I have a list of lists Aand a list of lists B, where Athey Bhave many identical sub-lists.

What is the best way to get unique inboxes from Band to A?

A = [['foo', 123], ['bar', np.array(range(10))], ['baz', 345]]
B = [['foo', 123], ['bar', np.array(range(10))], ['meow', 456]]

=> A = [['foo', 123], ['bar', np.array(range(10))], ['baz', 345], ['meow', 456]]

I tried:

A += [b for b in B if b not in A]

But it gives me ValueErrorspeaking to use any()or all(). Do I really need to check the item by item for each sublist in Bfor each sublist in A?

ERROR: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
+3
source share
2 answers

You can usually use one of many methods for a unique list or multiple lists in order or not.

Here is a way to uniquify two lists that do not support ordering:

>>> A=[1,3,5,'a','c',7]
>>> B=[1,2,3,'c','b','a',6]
>>> set(A+B)
set(['a', 1, 'c', 3, 5, 6, 7, 2, 'b'])

:

>>> seen=set()
>>> [e for e in A+B if e not in seen and (seen.add(e) or True)]
[1, 3, 5, 'a', 'c', 7, 2, 'b', 6]

, :

>>> set([np.array(range(10)), 22])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'

- repr :

>>> set([repr(e) for e in [np.array(range(10)), 22]])
set(['22', 'array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])'])

frozenset:

>>> set(frozenset(e) for e in [np.array(range(10)), np.array(range(2))])
set([frozenset([0, 1]), frozenset([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])])

frozenset :

>>> set(frozenset(e) for e in [[np.array(range(10)), np.array(range(2))],[np.array(range(5))
]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <genexpr>
TypeError: unhashable type: 'numpy.ndarray'

, .

, :

from collections import OrderedDict
import numpy as np

A = [['foo', 123], ['bar', np.array(range(10))], ['baz', 345]]
B = [['foo', 123], ['bar', np.array(range(10))], ['meow', 456]]

seen=OrderedDict((repr(e),0) for e in B)

newA=[]
for e in A+B:
    key=repr(e)
    if key in seen:
        if seen[key]==0:
            newA.append(e)
            seen[key]=1
    else:
        seen[key]=1
        newA.append(e)

print newA
# [['foo', 123], ['bar', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])], ['baz', 345], ['meow', 456]]

repr , eval , , . , .

, :

>>> repr(lambda x:x)
'<function <lambda> at 0x10710ec08>'

'<function <lambda> at 0x10710ec08>' - , 0x10710ec08 ( cPython ).

, , - frozenset , :

def flatten(LoL):
    for el in LoL:
        if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
            for sub in flatten(el):
                yield sub
        else:
            yield el      
newA=[]    
seen=set()
for e in A+B:
    fset=frozenset(flatten(e))
    if fset not in seen:
        newA.append(e)
        seen.add(fset)

print newA        
# [['foo', 123], ['bar', array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])], ['baz', 345], ['meow', 456]]

, , , repr B - . , .

+1

import numpy as np

A = [['foo', 123], ['bar', np.array(range(10))], ['baz', 345]]
B = [['foo', 123], ['bar', np.array(range(10))], ['meow', 456]]

res = set().update(tuple(x) for x in A).update(tuple(x) for x in B)

np.array, ... , .

0

All Articles