Python'daki bir listede bir şeyin olup olmadığını nasıl kontrol ederim?
En ucuz ve en okunabilir çözüm in
operatörü kullanmaktır (veya özel durumunuzda not in
). Belgelerde belirtildiği gibi,
Operatörler in
ve not in
üyelik testi. x in s
olarak değerlendirilirse
True
, eğer x
bir üyesidir s
ve False
aksi. x not in s
olumsuzluğunu döndürür x in s
.
Bunlara ek olarak,
Operatör not in
, ters gerçek değerine sahip olacak şekilde tanımlanır in
.
y not in x
mantıksal olarak aynıdır not y in x
.
İşte birkaç örnek:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
Bu aynı zamanda tuples ile de çalışır, çünkü tupler yıkanabilir (ayrıca değişmez olmalarının bir sonucu olarak):
(1, 2) in [(3, 4), (1, 2)]
# True
RHS üzerindeki nesne bir __contains__()
yöntem tanımlarsa , dokümanların Karşılaştırma bölümünün in
son paragrafında belirtildiği gibi dahili olarak çağıracaktır .
... in
ve not in
yinelenebilir veya __contains__()
yöntemi uygulayan türler tarafından desteklenir
. Örneğin, bunu yapabilirsiniz (ancak yapmamalısınız):
[3, 2, 1].__contains__(1)
# True
in
kısa devreler, bu nedenle öğeniz listenin in
başındaysa daha hızlı değerlendirir:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Bir öğenin listede olup olmadığını kontrol etmekten daha fazlasını yapmak istiyorsanız, seçenekler vardır:
list.index
bir öğenin dizinini almak için kullanılabilir. Bu öğe yoksa, a ValueError
yükseltilir.
list.count
olayları saymak istiyorsanız kullanılabilir.
XY Sorunu: Bunu düşündünüz mü set
?
Kendinize şu soruları sorun:
- bir öğenin listede birden fazla olup olmadığını kontrol etmeniz gerekiyor mu?
- Bu kontrol bir döngü içinde mi yoksa tekrar tekrar çağrılan bir fonksiyonda mı yapılıyor?
- Listenizde sakladığınız öğeler yıkanabilir mi? IOW,
hash
onları arayabilir misin ?
Bu sorulara "evet" yanıtı verdiyseniz, set
bunun yerine bir tane kullanmalısınız. S ile ilgili bir in
üyelik testi list
O (n) zaman karmaşıklığıdır. Bu, python'un listenizi doğrusal bir şekilde taraması, her bir öğeyi ziyaret etmesi ve arama öğesiyle karşılaştırması gerektiği anlamına gelir. Bunu tekrar tekrar yapıyorsanız veya listeler büyükse, bu işlem bir ek yüke neden olur.
set
nesneler ise sürekli üyelik kontrolü için değerlerini toplar. Kontrol ayrıca aşağıdakiler kullanılarak yapılır in
:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Aradığınız / aramadığınız öğenin listenizin sonunda olması konusunda talihsizseniz, python listeyi sonuna kadar taramış olacaktır. Bu, aşağıdaki zamanlamalardan açıkça görülmektedir:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Bir hatırlatma olarak, sakladığınız ve aradığınız öğeler yıkanabilir olduğu sürece bu uygun bir seçenektir. IOW, ya değişmez tipler ya da uygulayan nesneler olmalıdırlar __hash__
.
3 -1 > 0 and (4-1 , 5) not in []
⤇True
nedenle hata operatör öncelik biri değildir.