Pythonでリストを深く検索したい。たとえば、5 が入っているかどうかを知りたいmy_list
。
my_list = [2, [3, 4, [2, 3]], 1, [4, [5]]]
どうやってやるの?
マルチレベルのネストでこれを行う簡単な方法はわかりませんが、次のような再帰的アルゴリズムでうまくいきます。
def nestedSearch(nested, v):
for element in nested:
if isinstance(element, list):
if nestedSearch(element, v):
return True
elif element == v:
return True
return False
マルチネストされたリストをフラット化するために、これを見ることもできます:
flatten
関数( の再帰バージョンと考えてくださいitertools.chain
) を Python の標準in
演算子 (ジェネレーターでは線形検索を行います)と組み合わせて、これを取得できます。
>>> def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
>>> my_list = [2, [3, 4, [2, 3]], 1, [4, [5]]]
>>> 5 in flatten(my_list)
True
リンクされた質問のコメントflatten
に従って、検索対象が反復可能な場合はコードを改良する必要があります。たとえば、タプルはリストと同じように検索にフラット化され、文字列の検索は Python のスタック制限に達するまで再帰します。
リストのリストがある場合は、このアプローチを使用できます
>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> [item for sublist in l for item in sublist]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 5 in [item for sublist in l for item in sublist]
True
最初にリストを平坦化し、O(n) を使用してそれを検索します。
あなたのリストがあなたの例のように見える場合、forループを使用する以外にそれを行う別の方法は考えられません...
それを行う1つの方法:
def deapSearch(searchElement, searchList):
for element in searchList:
if element == searchElement:
return True
elif type(element) == type(list):
found = deapSearch(searchElement, element)
if found:
return found
return False
deapSearch(5, my_list)
True
deapSearch(4, my_list)
True
美しいではありませんが、働いています。
整数または文字を含むネストされたリストしかない場合、この問題を解決する 1 つの方法は、すべての不要な要素を含まない ( '[' 、 ']' ... を含まない) リストを作成することです。
chars を持つネストされたリストがあるとしましょう:
>>> nested = [[[[['F', 'B'], 'G'], ['D', 'A']], 'C'], 'E']
>>> string = str(nested)
>>> string = string.replace('[','',len(string))
>>> string = string.replace(']','',len(string))
>>> string = string.replace("'","",len(string))
>>> string = string.replace(" ","",len(string))
>>> string = string.split(',')
それは与えます :
>>> print (string)
['F', 'B', 'G', 'D', 'A', 'C', 'E']
これで、ループなしで簡単に検索できます:
>>> 'F' in string
True