4

Python 2.7.x で、ネストされたタプルに文字列 (または他のデータ型) が存在するかどうかを確認するための最良の (そして最速の) 方法は何ですか?

例えば:

RECIPES = (
    ('apple', 'sugar', 'extreme_Force'),
    ('banana', 'syrup', 'magical_ends'),
    ('caramel', 'chocolate', 'pancake_MONSTER'),
    ('banana',('someAnother','banana'))
)

このタプルbananaは、ネストされたタプルのいずれかに表示されるかどうかを確認し、場所のインデックス (この場合は ) を返す必要があります1,0

また、タプルは任意の深さにネストできます。

4

4 に答える 4

7

再帰的なマルチロケーション インデックス作成:

import sys
from collections import Sequence,defaultdict

#making code python3-compatible
if sys.version_info[0] == 3:
    basestring = str

def buildLocator(tree):
    locator = defaultdict(list)
    def fillLocator(tree, locator,location):
        for index,item in enumerate(tree):            
            if isinstance(item,basestring):
                locator[item].append(location+(index,))
            elif isinstance(item,Sequence):
                fillLocator(item,locator, location+(index,))
    fillLocator(tree,locator,())
    return locator

RECIPES = (
    ('apple', 'sugar', 'extreme_Force'),
    ('banana', 'syrup', 'magical_ends'),
    ('caramel', 'chocolate', 'pancake_MONSTER'),
    ('banana',('someAnother','banana'))
)
locator = buildLocator(RECIPES)

print(locator['banana'])

版画

[(1, 0), (3, 0), (3, 1, 1)]
于 2012-09-18T19:18:07.287 に答える
4

最初の一致のみが必要な場合、ジェネレーターはこれをうまく行うことができます。

def find_location(text):
    try:
        return next((i, j) 
            for i, t in enumerate(RECIPES)
            for j, v in enumerate(t)
            if v == text)
    except StopIteration:
        return (None, None)  # not found

使用法:

>>> find_location('banana')
(1, 0)
>>> find_location('apple')
(0, 0)
>>> find_location('chocolate')
(2, 1)
>>> find_location('spam')
(None, None)

RECIPES最初の値はシーケンス全体へのインデックスであり、2 番目の値は個々のタプルへのインデックスであることに注意してください。RECIPES[1][0] == 'banana'

于 2012-09-18T19:07:59.377 に答える
1

for ループを使用して項目が存在するかどうかを確認し、見つかったらすぐにループを中断します。

In [48]: RECIPES = (
   ....:     ('apple', 'sugar', 'extreme_Force'),
   ....:     ('banana', 'syrup', 'magical_ends'),
   ....:     ('caramel', 'chocolate', 'pancake_MONSTER'),
   ....: )

In [49]: for i,x in enumerate(RECIPES):
   ....:     if 'banana' in x:
   ....:         print i,x.index('banana')
   ....:         break
   ....:         
   ....:         
1 0
于 2012-09-18T19:10:11.297 に答える
1

試してみませんnumpyか?

import numpy as np
RECIPES = (
    ('apple', 'sugar', 'extreme_Force'),
    ('banana', 'syrup', 'magical_ends'),
    ('caramel', 'chocolate', 'pancake_MONSTER'),
)
np_recipes = np.array(recipes)
indices = zip(*np.where( np_recipes == 'banana' ) ) #[(1, 0)]

データが適切に並べられているため、これはあなたの例ではうまくいきます。あなたが尋ねたように、これは任意のネストでは機能しないことに注意してください(ただし、他の誰かが同様のより制約された質問でこれを見つけた場合に備えて、ここに残します)。

于 2012-09-18T19:16:30.923 に答える