Extrakce a nahrazení prvků, které splňují podmínky seznamu (pole) řetězců v jazyce Python

Podnikání

K vytvoření nového seznamu ze seznamu (pole), jehož prvky jsou řetězce, vyjmutím pouze těch prvků řetězců, které splňují určité podmínky, nebo provedením substitucí, konverzí atd., slouží seznamy s porozuměním.

Po stručném vysvětlení pojmů seznam comprehensions je vysvětlen následující obsah s ukázkovým kódem.

  • Extrakce na základě toho, zda je či není obsažen určitý řetězec (částečná shoda)
  • Nahradit konkrétní řetězec
  • Výpis podle toho, zda začíná nebo nezačíná určitým řetězcem
  • Výpis podle toho, zda končí nebo nekončí určitým řetězcem
  • Posuzováno a extrahováno podle jednotlivých případů
  • Převod velkých a malých písmen
  • určuje, zda se používají abecední nebo číselné znaky, a extrahuje je.
  • Více podmínek
  • (počítačový) regulární výraz

Všimněte si, že seznamy mohou uchovávat různé typy dat a striktně se liší od polí. Pokud chcete s poli pracovat v procesech, které vyžadují velikost paměti a paměťové adresy nebo numerické zpracování velkých dat, použijte pole (standardní knihovna) nebo NumPy.

zápis zařazení do seznamu

Při generování nového seznamu ze seznamu je zápis seznamů jednodušší než zápis cyklů for.

[expression for any variable name in iterable object if conditional expression]

Pokud má být prvek vybrán pouze podmíněným výrazem, není zpracován výrazem, takže má následující podobu

[variable name for variable name in original list if conditional expression]

Pokud se z podmíněného výrazu if vytvoří podmíněný výraz if not, stane se z něj negace a prvky, které nesplňují podmíněný výraz, lze vyjmout.

Obsahuje určitý řetězec (částečná shoda) \ Neobsahuje: in

V položce „konkrétní řetězec v původním řetězci“ vrací hodnotu True, pokud původní řetězec obsahuje konkrétní řetězec. Jedná se o podmíněný výraz.

Negace in se provádí pomocí not in.

l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']

l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']

l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']

Nahradit konkrétní řetězec

Pokud chcete nahradit řetězec prvků seznamu, použijte metodu replace() pro každý prvek v zápisu porozumění seznamu.

Pokud neexistuje řetězec, který má být nahrazen, není třeba vybírat prvek v podmíněném výrazu if, protože se použitím funkce replace() nezmění.

l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']

Pokud chcete nahradit celý prvek, který obsahuje určitý řetězec, extrahujte jej pomocí in a zpracujte pomocí ternárního operátoru. Ternární operátor se zapisuje v následujícím tvaru.
True Value if Conditional Expression else False Value

Je v pořádku, pokud je výrazovou částí zápisu porozumění seznamu ternární operátor.

l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']

Následuje shrnutí výsledků, které je uvedeno v závorkách. Pokud nejste zvyklí používat závorky, může vám to usnadnit pochopení a vyhnout se chybám. Z gramatického hlediska není problém, ani když závorky napíšete.

[('ZZZ' if ('XXX' in s) else s) for s in l]

Použití in jako podmínky je matoucí s notací pro porozumění seznamu in, ale není to obtížné, pokud jste si vědomi syntaktické podoby notace pro porozumění seznamu a ternárních operátorů.

Začíná určitým řetězcem \ nezačíná: startswith()

Metoda startswith() vrací true, pokud řetězec začíná řetězcem zadaným v argumentu.

l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']

l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']

Končí určitým řetězcem znaků \ nekončí: endswith()

Metoda endswith() vrací true, pokud řetězec končí řetězcem zadaným v argumentu.

l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']

l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']

Posuzováno a extrahováno podle jednotlivých případů

Metody isupper(),islower() lze použít k určení, zda je řetězec psán pouze velkými nebo pouze malými písmeny.

l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']

Převod velkých a malých písmen

Pokud chcete převést všechny znaky na velká nebo malá písmena, použijte metody upper() a lower(). Mezi další metody patří capitalize(), která píše velká písmena pouze jako první, a swapcase(), která prohodí velká a malá písmena.

Stejně jako v příkladu substituce výše použijte ternární operátor, pokud chcete zpracovat pouze prvky, které splňují podmínku.

l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']

l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']

určuje, zda se používají abecední nebo číselné znaky, a extrahuje je.

Metody isalpha() a isnumeric() lze použít k určení, zda je řetězec celý abecední, číselný atd.

l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']

l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']

Více podmínek

Součástí podmíněného výrazu v seznamu comprehensions může být více podmínek. Lze použít i záporné podmínky „not“.

Při použití tří nebo více podmíněných výrazů je bezpečnější uzavřít každou skupinu do závorek (), protože výsledek se bude lišit v závislosti na pořadí.

l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']

l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']

(počítačový) regulární výraz

Regulární výrazy umožňují velmi flexibilní zpracování.

Objekt shody vrácený funkcí re.match() je při vyhodnocení pomocí podmíněného výrazu vždy určen jako pravdivý. Pokud se neshoduje, vrací None, což je v podmíněném výrazu false. Pokud tedy chcete vyjmout pouze prvky, které odpovídají regulárnímu výrazu, stačí aplikovat re.match() na část podmíněného výrazu výrazu pro pochopení seznamu jako dříve.

import re

l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']

l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']

Užitečná je také funkce re.sub(), která nahrazuje odpovídající část regulárního výrazu. Chcete-li extrahovat a nahradit pouze odpovídající prvky, stačí přidat „if podmíněný výraz“.

l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']

l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']