Bagaimana cara memeriksa apakah semua item berikut ada dalam daftar?


114

Saya menemukan, bahwa ada pertanyaan terkait, tentang bagaimana menemukan jika setidaknya satu item ada dalam daftar:
Bagaimana cara memeriksa apakah salah satu dari item berikut ada dalam daftar?

Tapi apa cara terbaik dan pythonic untuk mengetahui apakah semua item ada dalam daftar?

Mencari melalui dokumen saya menemukan solusi ini:

>>> l = ['a', 'b', 'c']
>>> set(['a', 'b']) <= set(l)
True
>>> set(['a', 'x']) <= set(l)
False

Solusi lain adalah ini:

>>> l = ['a', 'b', 'c']
>>> all(x in l for x in ['a', 'b'])
True
>>> all(x in l for x in ['a', 'x'])
False

Tapi di sini Anda harus lebih banyak mengetik.

Apakah ada solusi lain?


5
Ada apa dengan set(smaller) <= set(larger)?
eumiro

1
Saya pikir solusi kedua Anda dengan 'semua' terlihat baik-baik saja dan pythonic bagi saya.
Jiho Noh

Jawaban:


157

Operator seperti <=di Python umumnya tidak diganti menjadi sesuatu yang sangat berbeda dari "kurang dari atau sama dengan". Ini tidak biasa untuk perpustakaan standar yang melakukan ini - baunya seperti API warisan bagi saya.

Gunakan metode yang setara dan lebih jelas namanya set.issubset,. Perhatikan bahwa Anda tidak perlu mengubah argumen menjadi satu set; itu akan melakukannya untuk Anda jika diperlukan.

set(['a', 'b']).issubset(['a', 'b', 'c'])

2
tidak tahu Anda bisa meneruskan daftar secara langsung sebagai argumen untuk issubset ... bagus!
tsimbalar

1
Meskipun saya setuju dengan sentimen tersebut, saya cukup setuju dengan gagasan <=dan issubsetarti yang sama. Mengapa Anda tidak menyukainya?
Kirk Strauser

2
@Hanya: Terutama, karena tidak jelas apa <=artinya set tanpa mencarinya di dokumen atau memiliki pengetahuan sebelumnya tentang apa artinya dalam teori himpunan, sedangkan semua orang tahu apa issubsetartinya secara otomatis.
Glenn Maynard

2
Anda tahu operator matematika untuk subset (non-proper)? pada dasarnya terlihat sangat mirip dengan <=;)
dom0

suka solusi ini. apakah ada cara untuk mendapatkan lokasi indeks atau nilai daftar alih-alih bool (True: False)?
Vlad Gulin

62

Saya mungkin akan menggunakan setdengan cara berikut:

set(l).issuperset(set(['a','b'])) 

atau sebaliknya:

set(['a','b']).issubset(set(l)) 

Saya merasa ini sedikit lebih mudah dibaca, tetapi mungkin terlalu mematikan. Set sangat berguna untuk menghitung persatuan / persimpangan / perbedaan antara koleksi, tetapi ini mungkin bukan pilihan terbaik dalam situasi ini ...


Sebenarnya, MySet.issubset(MyOtherSet)dan MySet <= MyOtherSetsama saja.
Wajan

1
@wok: oh saya tidak tahu itu, tapi menurut saya <= sintaks agak membingungkan karena sintaks yang mirip dapat digunakan dengan daftar, tetapi dengan arti yang sangat berbeda.
tsimbalar

3
tidak terlalu membingungkan jika Anda ingat penyertaan mendefinisikan urutan parsial pada set set mana pun. Sebenarnya agak membingungkan yang <=memiliki arti yang dilakukannya untuk urutan: orang mungkin berharap itu berarti 'adalah lanjutan' daripada urutan leksikografis.
aaronasterling

1
@aaronasterling: mmm, saya pribadi tidak terlalu memikirkan "urutan parsial" ketika saya mengetik kode :-), tapi saya setuju dengan fakta bahwa menggunakan <=dengan urutan juga terasa aneh, entah bagaimana ...
tsimbalar

3
Aku berlari ke gotcha sedikit di sini saya ingin menyebutkan: Jika Anda menggunakan metode ini, Anda sedang mengubah daftar Anda untuk set, yang berarti tidak ada duplikat. set(['a','a']).issubset(['a'])kembali True.
Orangestar

11

Saya suka keduanya karena mereka tampak paling logis, yang terakhir lebih pendek dan mungkin tercepat (ditampilkan di sini menggunakan setsintaks literal yang telah di- backport ke Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b'])
#   or
{'a', 'b'}.issubset({'a', 'b', 'c'})

Solusi "semua" adalah yang tercepat saat Anda mengukurnya dengan timeit (). Ini harus menjadi jawaban yang diterima.
Attersson

3

Bagaimana jika daftar Anda berisi duplikat seperti ini:

v1 = ['s', 'h', 'e', 'e', 'p']
v2 = ['s', 's', 'h']

Set tidak mengandung duplikat. Jadi, baris berikut mengembalikan True.

set(v2).issubset(v1)

Untuk menghitung duplikat, Anda dapat menggunakan kode:

v1 = sorted(v1)
v2 = sorted(v2)


def is_subseq(v2, v1):
    """Check whether v2 is a subsequence of v1."""
    it = iter(v1)
    return all(c in it for c in v2) 

Jadi, baris berikut mengembalikan False.

is_subseq(v2, v1)

1

Ini adalah apa yang saya cari secara online tetapi sayangnya tidak ditemukan secara online tetapi saat bereksperimen dengan penerjemah python.

>>> case  = "caseCamel"
>>> label = "Case Camel"
>>> list  = ["apple", "banana"]
>>>
>>> (case or label) in list
False
>>> list = ["apple", "caseCamel"]
>>> (case or label) in list
True
>>> (case and label) in list
False
>>> list = ["case", "caseCamel", "Case Camel"]
>>> (case and label) in list
True
>>>

dan jika Anda memiliki daftar variabel yang terlalu banyak di file sublist variable

>>>
>>> list  = ["case", "caseCamel", "Case Camel"]
>>> label = "Case Camel"
>>> case  = "caseCamel"
>>>
>>> sublist = ["unique banana", "very unique banana"]
>>>
>>> # example for if any (at least one) item contained in superset (or statement)
...
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
False
>>>
>>> sublist[0] = label
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>> # example for whether a subset (all items) contained in superset (and statement)
...
>>> # a bit of demorgan's law
...
>>> next((False for item in sublist if item not in list), True)
False
>>>
>>> sublist[1] = case
>>>
>>> next((False for item in sublist if item not in list), True)
True
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>>

0

Contoh cara melakukan ini menggunakan ekspresi lambda adalah:

issublist = lambda x, y: 0 in [_ in x for _ in y]

1
Silakan tambahkan komentar untuk menjelaskan / menguraikan jawaban Anda
Sharad

0

Bukan kasus OP, tetapi - untuk siapa saja yang ingin menegaskan persimpangan di penis dan berakhir di sini karena googling yang buruk (misalnya saya) - Anda perlu bekerja dengan dict.items:

>>> a = {'key': 'value'}
>>> b = {'key': 'value', 'extra_key': 'extra_value'}
>>> all(item in a.items() for item in b.items())
True
>>> all(item in b.items() for item in a.items())
False

Itu karena dict.itemsmengembalikan tupel pasangan kunci / nilai, dan seperti objek lainnya di Python, keduanya dapat dibandingkan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.