Python liste öğesinin başka bir dizenin içinde bir dize içerip içermediğini kontrol edin


587

Bir listem var:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

ve dizeyi içeren öğeleri aramak istersiniz 'abc'. Bunu nasıl yapabilirim?

if 'abc' in my_list:

olmadığını kontrol ediyorum 'abc'listesinde mevcut ama bir parçasıdır 'abc-123've 'abc-456', 'abc'kendi başına yok. Peki, içerdiği tüm öğeleri nasıl alabilirim 'abc'?


19
Tersini kontrol etmek için (bir dize birden fazla dize arasında bir tane içeriyorsa): stackoverflow.com/a/6531704/2436175
Antonio

Girişlerin sol bölümleri benzersizse, listeden bir diksiyon oluşturmayı düşünün: Kısmi bir dizeye dayanan bir listede giriş bulun
Georgy

Yanıtlar:


930

Yalnızca abclistedeki herhangi bir dizede bulunup bulunmadığını kontrol etmek istiyorsanız ,

some_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
if any("abc" in s for s in some_list):
    # whatever

İçerdiği tüm öğeleri gerçekten almak istiyorsanız abc,

matching = [s for s in some_list if "abc" in s]

Bir öğenin 6 öğeden oluşan bir dizide olup olmadığını kontrol etmeliyim. 6 "if" yapmak daha mı hızlı ya da aynı mı?
Olivier Pons

42
@OlivierPons, sadece yapif myitem in myarray:
alldayremix 21:13

8
'Abc' alt dizesi içeren tüm dizeleri almanın başka bir yolu:filter(lambda element: 'abc' in element, some_list)
driftcatcher 31:13

2
@ p014k: index()yöntemi kullanın :try: return mylist.index(myitem); except ValueError: pass
Sven Marnach

1
@midkin: Ne tam olarak ne yapmaya çalıştığınızı ya da nasıl yanlış gittiğini anlamıyorum. Muhtemelen yeni bir soru sorarak ("Soru Sor" düğmesiyle), tam kodunuzu, kodun ne yapmasını beklediğinizi ve gerçekte ne yaptığını kopyalayarak daha fazla şansınız olacaktır. Bu bağlamda "işe yarayan" ın ne anlama geldiğini tanımlamazsanız "işe yaramadı" tamamen anlamsızdır, ancak o zaman bile gerçekte ne olduğunu açıklamak yerine ne olduğunu açıklamak daha iyidir.
Sven Marnach

104

Sadece bunu oraya atmak: Örneğin, birden fazla dizeyle eşleşmeniz gerekiyorsa abcve defiki kavrayışı aşağıdaki gibi birleştirebilirsiniz:

matchers = ['abc','def']
matching = [s for s in my_list if any(xs in s for xs in matchers)]

Çıktı:

['abc-123', 'def-456', 'abc-456']

4
Bu tam ben için googling oldu .. Teşekkürler!
N8TRO

2
Ayrıca kullanabilirsiniz {s for s in my_list for xs in matchers if xs in s}(benzersiz bir küme oluşturmak için süslü parantezlere dikkat edin). Okuması daha kolay olabilir, ancak çoğu sdeğerin bir eşleşmesi olacaksa daha yavaş olabilir , çünkü anyilk maçta etkili bir şekilde duracaksınız.
Matthias Fripp

82

Sahip filterolan öğelere ulaşmak için kullanın abc.

>>> lst = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
>>> print filter(lambda x: 'abc' in x, lst)
['abc-123', 'abc-456']

Bir liste kavrayışı da kullanabilirsiniz.

>>> [x for x in lst if 'abc' in x]

Bu arada, sözcüğü listzaten listtür için kullanıldığı için değişken adı olarak kullanmayın .


50

Eğer 'abc' öğelerinden birinde olup olmadığını bilmeniz gerekiyorsa, bu en kısa yoldur:

if 'abc' in str(my_list):

1
'Abc' dizesi yeni oluşturulan dizede
cgseller 26:17

2
Evet, amaçlanan davranış budur ... öğelerden herhangi biri 'abc' içeriyorsa doğrudur
RogerS

7
Diğer tüm insanların neden bu kıvrımlı lambda çözümlerini ihtiyaç duymadıklarında yapmaya karar verdiklerini bilmiyorum! Güzel iş @RogerS
ntk4

1
Aslında aynı soru neredeyse cevaplıyor ... Ben sadece 3 harf ekledim.
RogerS

1
Bu güzel bir çözüm, ancak verilen dizeyi içeren öğeleri bulmak istiyorsanız başarılı olmazsınız. Burada , öğelerin herhangi birinin dizeyi içerip içermediğini öğrenirsiniz.
cslotty

18

Bu oldukça eski bir soru, ama bu cevabı öneriyorum çünkü önceki cevaplar listede dizeler olmayan öğelerle (ya da bir çeşit yinelenebilir nesne) başa çıkmıyor. Bu tür öğeler, bir liste istisnasıyla liste kavramasının başarısız olmasına neden olur.

Yinelenemeyen öğeleri atlayarak listedeki bu tür öğeleri incelikle ele almak için aşağıdakileri kullanın:

[el for el in lst if isinstance(el, collections.Iterable) and (st in el)]

sonra, böyle bir liste ile:

lst = [None, 'abc-123', 'def-456', 'ghi-789', 'abc-456', 123]
st = 'abc'

eşleşen öğeleri almaya devam edersiniz (['abc-123', 'abc-456'] )

Tekrarlanabilirlik testi en iyi olmayabilir. Buradan anladım: Python'da bir nesnenin yinelenebilir olup olmadığını nasıl belirleyebilirim?


[el for el in lst if el and (st in el)]Verilen örnekte daha anlamlı olmaz mıydı ?
Gordo

@tinix Yinelenemeyen nesneleri incelikle işlemeyeceğim, değil mi?
Robert Muil

"verilen örnek" my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456'] bunu aşırı karmaşıklaştırmaya gerek yok.
Gordo

1
Evet kesinlikle - kabul edilen cevap mükemmel bir şekilde uygundur ve önerim daha karmaşıktır, bu yüzden bunu görmezden gelmek için çekinmeyin - Birisinin yaşadığım problemle karşılaşması durumunda teklif ettim: Bu listelerdeki tekrarlanamayan öğeler gerçek dünya olasılığıdır verilen örnekte mevcut olmamasına rağmen.
Robert Muil

13
x = 'aaa'
L = ['aaa-12', 'bbbaaa', 'cccaa']
res = [y for y in L if x in y]

10
for item in my_list:
    if item.find("abc") != -1:
        print item

3
Bu yaklaşımı benimseyecek olursanız, bence if 'abc' in itemkullanmak daha deyimseldir item.find('abc') == -1.
Wyatt Baldwin


4

__contains__()Pythons string sınıfı yöntemini kullanın :

a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for i in a:
    if i.__contains__("abc") :
        print(i, " is containing")

3

Python'da yeniyim. Aşağıdaki kod çalışma var ve kolay anlaşılır yaptı:

my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']
for str in my_list:
    if 'abc' in str:
       print(str)

0
my_list = ['abc-123', 'def-456', 'ghi-789', 'abc-456']

for item in my_list:
    if (item.find('abc')) != -1:
        print ('Found at ', item)

0
mylist=['abc','def','ghi','abc']

pattern=re.compile(r'abc') 

pattern.findall(mylist)

Python3.6'da bu bir hata verir: TypeError: beklenen dize veya bayt benzeri nesne
AimForClarity

1
@AimForClarity Evet. python3.6'daki re.findall bir dize bekliyor. Bir alternatif listeyi bir dizeye dönüştürmek olabilir import re mylist=['abc','def','ghi','abcff'] my_list_string=''.join(mylist) string_to_find="abc" res=re.findall(string_to_find,my_list_string) print(res)
arun_munagala

1
Kötü biçimlendirme için özür dileriz. Herhangi bir nedenle uygun satır sonları yapılamadı.
arun_munagala

0

Belirli bir değeri girmenizi gerektiren bir arama yaptım, o zaman girişinizi içeren listeden bir değer arayacaktır:

my_list = ['abc-123',
        'def-456',
        'ghi-789',
        'abc-456'
        ]

imp = raw_input('Search item: ')

for items in my_list:
    val = items
    if any(imp in val for items in my_list):
        print(items)

'Abc' için arama yapmayı deneyin.


0
def find_dog(new_ls):
    splt = new_ls.split()
    if 'dog' in splt:
        print("True")
    else:
        print('False')


find_dog("Is there a dog here?")

0

Aşağıdaki gibi bir eşleşmeye karşılık gelen liste indekslerine ihtiyacım vardı :

lst=['abc-123', 'def-456', 'ghi-789', 'abc-456']

[n for n, x in enumerate(lst) if 'abc' in x]

çıktı

[0, 3]

-1

Soru: abc hakkında bilgi veriniz

    a = ['abc-123', 'def-456', 'ghi-789', 'abc-456']


    aa = [ string for string in a if  "abc" in string]
    print(aa)

Output =>  ['abc-123', 'abc-456']

-2

Bildiğim kadarıyla bir 'for' ifadesi her zaman zaman harcayacaktır.

Liste uzunluğu büyüdüğünde, yürütme süresi de büyüyecektir.

Ben bir dize 'is' deyimi ile bir dize arama biraz daha hızlı olduğunu düşünüyorum.

In [1]: t = ["abc_%s" % number for number in range(10000)]

In [2]: %timeit any("9999" in string for string in t)
1000 loops, best of 3: 420 µs per loop

In [3]: %timeit "9999" in ",".join(t)
10000 loops, best of 3: 103 µs per loop

Ancak, anyifadenin daha okunabilir olduğunu kabul ediyorum .

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.