Bir dizenin Python'daki listeden bir öğe içerip içermediğini kontrol etme


217

Böyle bir şey var:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

Python (for loop kullanmadan) bunu yapmak için daha zarif bir yol ne olacağını merak ediyorum? (C / C ++ gibi) böyle bir şey düşünüyordum, ama işe yaramadı:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

Düzenleme: Bu nasıl potansiyel yinelenen (yani sanırım kapalı alamadım) olarak işaretlenmiş aşağıdaki sorudan farklı açıklamak zorundayım.

Fark, bir dize dizelerin bazı listesinin bir parçası olup olmadığını kontrol etmek istedim, diğer soru ise dizeler listesinden bir dize başka bir dizenin bir alt dizesi olup olmadığını kontrol ediyor. Benzer, ancak aynı değil ve anlambilim, çevrimiçi IMHO'ya cevap ararken önemlidir. Bu iki soru aslında birbirinin zıt problemini çözmeye çalışıyor. Her ikisinin de çözümü aynıdır.


Yanıtlar:


421

anyİlk True cihazında kısa devrelerle birlikte bir jeneratör kullanın :

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

EDIT: Bu cevabın OP tarafından kabul edildiğini görüyorum. Benim çözümüm onun özel sorun için "yeterince iyi" bir çözüm olabilir ve bir listedeki herhangi bir dizenin başka bir dizede bulunup bulunmadığını kontrol etmek için iyi bir genel yol olsa da, bu çözümün yaptığı tek şey olduğunu unutmayın. Dizenin NEREDE olduğu yerde NEREDE bulunduğunu umursamaz . Bu önemliyse, genellikle URL'lerde olduğu gibi, @Wladimir Palant'ın cevabına bakmalısınız veya yanlış pozitif olma riskiyle karşı karşıya kalırsınız.


1
tam da aradığım şey buydu. benim durumumda dize nerede uzantısı önemli değil. teşekkürler
pootzko

Büyük öneri. Bu örneği kullanarak, argümanlardan herhangi birinin iyi bilinen yardım bayraklarıyla eşleşip eşleşmediğini nasıl kontrol ederim: ['-?', '- h', '- yardım', '/ h içindeki herhangi bir ([x.lower () '] sys.argv'deki x için [1:]])
AX Labs

@ AX-Labs, içerideki liste kavrayışlarını kullanan anykısa devrenin sağladığı olası kazanımların bazılarını ortadan kaldıracaktır, çünkü tüm liste her durumda oluşturulmalıdır. İfadeyi köşeli parantez ( any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:])) olmadan kullanırsanız, x.lower() in [...]parça yalnızca True değeri bulunana kadar değerlendirilir.
Lauritz V. Thaulow

5
Ve any () True döndürdüğünde ext'in ne olduğunu bilmek istersem?
Peter Senna

@PeterSenna: any()sadece doğru veya yanlış döndürür , ancak bu değişiklikle birlikte @psun'un liste anlama cevabına bakın:print [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
Bu akıllıca - tuples bunu yapabileceğini bilmiyordum!, ama sadece alt dize dize bir ucuna demirlendiğinde çalışır.
Dannid

3
Çok havalı. Keşke sadece başlar ya da biter yerine "içerir" gibi bir şey olsaydı
BrDaHa 23

@BrDaHa için 'in' kullanabilirsiniz içerir. listede 'string' ise:
Shekhar Samanta

@ShekharSamanta elbette, ancak bu, birden fazla şeyden birinin bir dizede olup olmadığını kontrol etme sorununu çözmez, yani orijinal soru budur.
BrDaHa

Evet bu durumda şunu kullanabiliriz: if any (string.split içindeki öğe (listedeki öğe için 'herhangi bir delmiter')) ve varsa string için (listedeki öğe için dizedeki öğe)
Shekhar Samanta

21

URL'yi doğru şekilde ayrıştırmak daha iyidir - bu şekilde http://.../file.doc?foove http://.../foo.doc/file.exedoğru şekilde işleyebilirsiniz .

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

Tek satırlık bir çözüm istiyorsanız, liste kavrayışlarını kullanın. Aşağıdaki kod, .doc, .pdf ve .xls uzantılarına sahip olduğunda url_string öğesini içeren bir liste döndürür veya uzantı içermediğinde boş liste döndürür.

print [url_string for extension in extensionsToCheck if(extension in url_string)]

NOT: Bu, yalnızca içerip içermediğini kontrol etmek içindir ve uzantılarla eşleşen tam kelimeyi çıkarmak istediğinde yararlı değildir.


Bu anyçözümden daha okunabilir , bence bu soru için mümkün olan en iyi çözümlerden biri.
Dmitry Verhoturov

Bu seferki üstündür any()o kadar gibi, hem de belirli eşleştirme değeri döndürmek için değiştirilebilir çünkü bence çözümü: print [extension for extension in extensionsToCheck if(extension in url_string)](ek ayrıntılar için Cevabımı görmek ve nasıl eşleştirme ayıklamak için kelime URL_STRING gelen desen yanı sıra)
Dannid

2

Bu normal ifadeyle eşleşip eşleşmediğini kontrol edin:

'(\.pdf$|\.doc$|\.xls$)'

Not: uzantılarınız URL'nin sonunda değilse, $karakterleri kaldırın , ancak biraz zayıflatır


1
Bu bir URL, bir sorgu dizesi varsa ne olur?
Wladimir Palant

import re re.search (desen, diziniz)
juankysmith

bu yanıt belirtilen vaka için geçerli olsa da, ölçeklenebilir veya genel değildir. eşleştirmek istediğiniz her model için uzun bir normal ifadeye ihtiyacınız vardır.
Dannid

1

Bu @psun tarafından verilen liste anlama cevabının bir çeşididir.

Çıktı değerini değiştirerek, eşleşen deseni liste kavramadan çıkarabilirsiniz ( any()@ Lauritz-v-Thaulow yaklaşımıyla mümkün olmayan bir şey )

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

[ 'Doc'] '

Ayrıca, eşleşen desen bilindikten sonra ek bilgi toplamak istiyorsanız normal bir ifade ekleyebilirsiniz (bu izin verilen desenlerin listesi tek bir normal ifade desenine yazmak için çok uzun olduğunda yararlı olabilir)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.