475

2 つのフラット リストの共通部分を取得する方法を知っています。

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

また

def intersect(a, b):
    return list(set(a) & set(b))
 
print intersect(b1, b2)

しかし、ネストされたリストの交差点を見つけなければならないとき、私の問題が始まります:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

最後に、私は受け取りたいです:

c3 = [[13,32],[7,13,28],[1,6]]

これで手を貸してくれませんか?

関連している

4

21 に答える 21

896

交差を定義する必要はありません。それはすでにセットの一流の部分です。

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])
于 2009-03-13T14:16:46.673 に答える
179

お望みならば:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [[13, 32], [7, 13, 28], [1,6]]

次に、Python 2 のソリューションを次に示します。

c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]

Python 3filterでは の代わりに iterable を返すため、次のように呼び出しlistをラップする必要があります。filterlist()

c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]

説明:

フィルター部分は、各サブリストの項目を取得し、それがソース リスト c1 にあるかどうかを確認します。リスト内包表記は、c2 の各サブリストに対して実行されます。

于 2009-03-13T14:11:13.707 に答える
61

2 つのリストの交点を探しているだけの人のために、Asker は 2 つの方法を提供しました。

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(b1, b2)

しかし、3 つではなく、リスト/セット間の変換を 1 回だけ行う必要があるため、より効率的なハイブリッド メソッドがあります。

b1 = [1,2,3,4,5]
b2 = [3,4,5,6]
s2 = set(b2)
b3 = [val for val in b1 if val in s2]

これは O(n) で実行されますが、リスト内包表記を含む彼の元の方法は O(n^2) で実行されます。

于 2009-12-09T17:26:06.410 に答える
30

機能的アプローチ:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

1+リストのより一般的なケースに適用できます

于 2009-09-10T08:50:21.770 に答える
21

& 演算子は、2 つのセットの交点を取ります。

{1, 2, 3} & {2, 3, 4}
Out[1]: {2, 3}
于 2016-12-16T11:09:47.363 に答える
8

が定義されているのでintersect、基本的なリスト内包表記で十分です。

>>> c3 = [intersect(c1, i) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

S. Lott の発言と TM. の関連する発言のおかげで改善されました。

>>> c3 = [list(set(c1).intersection(i)) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]
于 2012-02-21T11:38:00.057 に答える
5

与えられた:

> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

セット操作を使用すると、次のコードがうまく機能し、おそらくより簡潔になることがわかりました。

> c3 = [list(set(f)&set(c1)) for f in c2] 

それは得ました:

> [[32, 13], [28, 13, 7], [1, 6]]

注文が必要な場合:

> c3 = [sorted(list(set(f)&set(c1))) for f in c2] 

私たちは得ました:

> [[13, 32], [7, 13, 28], [1, 6]]

ちなみに、よりPythonスタイルの場合、これも問題ありません。

> c3 = [ [i for i in set(f) if i in c1] for f in c2]
于 2014-04-12T08:21:15.613 に答える
3

あなたの質問に答えるのが遅れているかどうかはわかりません。あなたの質問を読んだ後、リストとネストされたリストの両方で機能する関数 intersect() を思いつきました。この関数を定義するために再帰を使用しましたが、非常に直感的です。それがあなたが探しているものであることを願っています:

def intersect(a, b):
    result=[]
    for i in b:
        if isinstance(i,list):
            result.append(intersect(a,i))
        else:
            if i in a:
                 result.append(i)
    return result

例:

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> print intersect(c1,c2)
[[13, 32], [7, 13, 28], [1, 6]]

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> print intersect(b1,b2)
[4, 5]
于 2012-06-30T23:23:23.130 に答える
2

[1,2]交差すると[1, [2]]思いますか? つまり、気にするのは数字だけですか、それともリスト構造ですか?

数字だけの場合は、リストを「平坦化」する方法を調べてから、そのset()方法を使用してください。

于 2009-03-13T13:45:14.957 に答える
1

私もそれを行う方法を探していましたが、最終的には次のようになりました。

def compareLists(a,b):
    removed = [x for x in a if x not in b]
    added = [x for x in b if x not in a]
    overlap = [x for x in a if x in b]
    return [removed,added,overlap]
于 2016-11-29T14:40:50.280 に答える
0

これには set メソッドを使用できます。

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

   result = [] 
   for li in c2:
       res = set(li) & set(c1)
       result.append(list(res))

   print result
于 2015-05-05T12:05:52.380 に答える
0
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

c3 = [list(set(c2[i]).intersection(set(c1))) for i in xrange(len(c2))]

c3
->[[32, 13], [28, 13, 7], [1, 6]]
于 2014-11-21T08:59:50.800 に答える
0
# Problem:  Given c1 and c2:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
# how do you get c3 to be [[13, 32], [7, 13, 28], [1, 6]] ?

c3セットを含まない設定方法の 1 つを次に示します。

c3 = []
for sublist in c2:
    c3.append([val for val in c1 if val in sublist])

しかし、1 行だけを使用したい場合は、次のようにすることができます。

c3 = [[val for val in c1 if val in sublist]  for sublist in c2]

これはリスト内包表記の中にあるリスト内包表記で、少し変わっていますが、それに従うのにそれほど苦労する必要はないと思います。

于 2017-08-24T20:19:39.337 に答える
0
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [list(set(i) & set(c1)) for i in c2]
c3
[[32, 13], [28, 13, 7], [1, 6]]

私にとって、これは非常にエレガントで迅速な方法です:)

于 2018-05-21T09:47:02.817 に答える
-1
from random import *

a = sample(range(0, 1000), 100)
b = sample(range(0, 1000), 100)
print(a)
print(b)
print(set(a).intersection(set(b)))
于 2022-01-11T22:30:00.013 に答える