Saya tahu cara mendapatkan persimpangan dua daftar datar:
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]
atau
def intersect(a, b):
return list(set(a) & set(b))
print intersect(b1, b2)
Tetapi ketika saya harus menemukan persimpangan untuk daftar bersarang maka masalah saya mulai:
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]]
Pada akhirnya saya ingin menerima:
c3 = [[13,32],[7,13,28],[1,6]]
Bisakah kalian bantu saya dengan ini?
Terkait
python
list
intersection
elfuego1
sumber
sumber
Jawaban:
Jika kamu mau:
Maka di sini adalah solusi Anda untuk Python 2:
Di Python 3
filter
mengembalikan iterable, bukanlist
, jadi Anda harus membungkusfilter
panggilan denganlist()
:Penjelasan:
Bagian filter mengambil setiap item sublist dan memeriksa untuk melihat apakah ada dalam daftar sumber c1. Pemahaman daftar dieksekusi untuk setiap sublist di c2.
sumber
filter(set(c1).__contains__, sublist)
untuk efisiensi. Namun, keuntungan dari solusi ini adalahfilter()
mempertahankan tipe string dan tuple.c3 = [[x for x in sublist if x in c1] for sublist in c2]
Anda tidak perlu mendefinisikan persimpangan. Ini sudah menjadi bagian dari kelas set.
sumber
set(b1) & set(b2)
? IMO pembersihnya untuk menggunakan operator.set
akan menyebabkan kode yang urutan besarnya lebih cepat. Inilah contoh benchmark®: gist.github.com/andersonvom/4d7e551b4c0418de3160Bagi orang-orang yang hanya ingin menemukan persimpangan dua daftar, Penanya menyediakan dua metode:
Tetapi ada metode hybrid yang lebih efisien, karena Anda hanya perlu melakukan satu konversi antara daftar / set, berbeda dengan tiga:
Ini akan berjalan di O (n), sedangkan metode aslinya yang melibatkan pemahaman daftar akan berjalan di O (n ^ 2)
sumber
Pendekatan fungsional:
dan itu dapat diterapkan pada kasus 1+ daftar yang lebih umum
sumber
set(*input_list[:1]).intersection(*input_list[1:])
. Versi Iterator (it = iter(input_list)
):reduce(set.intersection, it, set(next(it, [])))
. Kedua versi tidak perlu mengonversi semua daftar input untuk ditetapkan. Yang terakhir ini lebih hemat memori.from functools import reduce
untuk menggunakannya dalam Python 3. Atau lebih baik lagi, gunakanfor
loop eksplisit .Versi pemahaman daftar murni
Varian rata:
Varian bersarang:
sumber
Operator & mengambil persimpangan dua set.
sumber
Cara pythonic mengambil persimpangan 2 daftar adalah:
sumber
Anda harus meratakan menggunakan kode ini (diambil dari http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), kodenya belum teruji, tapi saya cukup yakin itu berhasil:
Setelah Anda meratakan daftar, Anda melakukan persimpangan dengan cara yang biasa:
sumber
Sejak
intersect
didefinisikan, pemahaman daftar dasar sudah cukup:Peningkatan berkat ucapan S. Lott dan komentar terkait TM:
sumber
Diberikan:
Saya menemukan kode berikut berfungsi dengan baik dan mungkin lebih ringkas jika menggunakan operasi yang ditetapkan:
Itu mendapat:
Jika pesanan diperlukan:
kita punya:
Omong-omong, untuk gaya python yang lebih banyak, yang ini juga baik-baik saja:
sumber
Saya tidak tahu apakah saya terlambat menjawab pertanyaan Anda. Setelah membaca pertanyaan Anda, saya datang dengan fungsi intersect () yang dapat bekerja pada daftar dan daftar bersarang. Saya menggunakan rekursi untuk mendefinisikan fungsi ini, sangat intuitif. Semoga ini yang Anda cari:
Contoh:
sumber
Apakah Anda mempertimbangkan
[1,2]
untuk bersinggungan[1, [2]]
? Artinya, apakah hanya angka yang Anda pedulikan, atau struktur daftar juga?Jika hanya angka-angka, selidiki bagaimana cara "meratakan" daftar, kemudian gunakan
set()
metode.sumber
Saya juga mencari cara untuk melakukannya, dan akhirnya berakhir seperti ini:
sumber
sumber
Kita dapat menggunakan metode yang ditetapkan untuk ini:
sumber
Untuk mendefinisikan persimpangan yang memperhitungkan kardinalitas elemen dengan benar, gunakan
Counter
:sumber
Berikut ini satu cara untuk menyetel
c3
yang tidak melibatkan set:Tetapi jika Anda lebih suka menggunakan satu baris saja, Anda bisa melakukan ini:
Ini adalah pemahaman daftar di dalam pemahaman daftar, yang agak tidak biasa, tapi saya pikir Anda seharusnya tidak mengalami terlalu banyak kesulitan untuk mengikutinya.
sumber
Bagi saya ini adalah cara yang sangat elegan dan cepat untuk itu :)
sumber
daftar datar dapat dibuat dengan
reduce
mudah.Yang Anda butuhkan untuk menggunakan initializer - argumen ketiga dalam
reduce
fungsi.Kode di atas berfungsi untuk python2 dan python3, tetapi Anda perlu mengimpor mengurangi modul sebagai
from functools import reduce
. Lihat tautan di bawah untuk detailnya.untuk python2
untuk python3
sumber
Cara sederhana untuk menemukan perbedaan dan persimpangan antara iterables
Gunakan metode ini jika pengulangan penting
sumber