8

私はPythonを初めて使用し、検索を行いましたが、探しているものが見つかりませんでした。この質問があり、達成しようとしていることの名前がわからないために見つからなかった場合は、事前にお詫び申し上げます。私はあなたが提案するかもしれないどんな文書でも喜んで読みます。

リストのリストがあります。例=>[int、'str']

t = [[0234, 'str_0'],
     [1267, 'str_1'],
     [2445, 'str_2']]

リストta strのリストの1つのindex(1)の位置に存在するかどうかを調べたい。これは、2つのforループまたはwhileループを含む関数で実行できますが、私が求めているのは、可能であれば、1回の反復を使用してこれを実現することです。最短の機能を学びたい。

for input str('str_3'), I want to get int(2)(独自の最初のインデックス位置にstr_3があるリストのインデックス)str_1の場合、int(0)を取得したい

str_1234の場合、 Falseはリスト内のどのリストにも含まれていないため、 Falseを取得したいと思います。list t

初心者として、私は通常次のことを行います。

for n in range(len(t)):
    if t[n][1] == 'str_1'
        return n
    return False

私が得ようとしているのは、可能であれば、コードの1行でこれを達成するためのより良い、より短い方法です。経験豊富な方がお勧めです。

ありがとうございました

4

4 に答える 4

11
[n for n, (i, s) in enumerate(t) if s == 'str_3']

説明:

>>> t = [[100, 'str_1'], [200, 'str_2'], [300, 'str_3']]

# Use enumerate to get each list item along with its index.
>>> list(enumerate(t))
[(0, [100, 'str_1']), (1, [200, 'str_2']), (2, [300, 'str_3'])]

# Use list comprehension syntax to iterate over the enumeration.
>>> [n for n, (i, s) in enumerate(t)]
[0, 1, 2]

# An if condition can be added right inside the list comprehension.
>>> [n for n, (i, s) in enumerate(t) if s == 'str_3']
[2]
>>> [n for n, (i, s) in enumerate(t) if s == 'str_1234']
[]

複数存在する可能性があるため、これにより一致するすべてのインデックスが返されます。

インデックスが1つしかないことがわかっている場合は、ネストされたリストの代わりにdictを使用することをお勧めしますか?dictを使用すると、反復する必要がなく、非常に単純な構文を使用して一定時間で要素を検索できます。

>>> t = {'str_1': 100, 'str_2': 200, 'str_3': 300}

>>> 'str_3' in t
True
>>> t['str_3']
300

>>> 'str_1234' in t
False
>>> t['str_1234']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'str_1234'
于 2012-08-18T15:37:35.640 に答える
7

ジェネレータ式でany関数を使用します。

any(el[1] == 'str_1' for el in t)

これはループオーバーtであり、ループのように、それぞれelt2番目の値がに等しいかどうかをテストしstr_1ます。

ただし、これは、これが真である要素が見つかるまでのみ実行され、その後停止して、を返しTrueます。そのような要素が見つからない場合は、False代わりに返されます。

代わりに、存在をテストするだけでなく、str_1それがどこにあるかを知りたい場合、最も効率的な方法は、行ったようにループを使用することです。を使用enumerateして、インデックスと値の両方を順番に指定できます。

for n, el in enumerate(t):
    if el[1] == 'str_1'
        return n
    return False
于 2012-08-18T15:41:13.143 に答える
3

提供するforループの例は、Pythonでforループを使用する通常の方法ではありません。これは、forループが数値構造ではなく(ほとんどの言語でそうであるように)、各要素にループ本体を適用する方法であるためです。与えられたコレクションの反復によって生成されます。

インデックスを見つける通常の方法(ループを使用)は次のようになります。

for (n, (integer, string)) in enumerate(t):
    if 'str1' == string:
        return n

この場合、シーケンス割り当てを使用して、各2項目リストの要素を個別の変数に割り当てることに注意してください。enumeratePythonシェルで関数を自分で試して、その機能を確認してください。

リストが並べ替えられている場合は、代わりに次を使用することをお勧めしますbisect: http: //docs.python.org/library/bisect.html

条件に一致するペアがあるかどうかを確認したいだけで、インデックスを気にしない場合は、を使用しますany。これは、一致するものが見つかると反復を停止します。

any(string == 'str_1' for integer, string in t)

内部の式anyジェネレータ式であり、tの各要素に対してTrueまたはを生成します。False

最後に、これが本当に使用するのに最も適切なデータ構造であるかどうかを検討してください。

于 2012-08-18T15:42:37.587 に答える
1

まず、あなたが説明しているものと同様の実際のデータ構造を実行しましょう。

>>> LoL=[[i,'str_{}'.format(i)] for i in list(range(10))+list(range(10,0,-1))]
# this is Py 3, so that is why I need 'list' around range
>>> LoL
[[0, 'str_0'], [1, 'str_1'], [2, 'str_2'], [3, 'str_3'], [4, 'str_4'], [5, 'str_5'], 
 [6, 'str_6'], [7, 'str_7'], [8, 'str_8'], [9, 'str_9'], [10, 'str_10'], [9, 'str_9'], 
 [8, 'str_8'], [7, 'str_7'], [6, 'str_6'], [5, 'str_5'], [4, 'str_4'], [3, 'str_3'], 
 [2, 'str_2'], [1, 'str_1']]

次に、「str_5」に等しいテストに一致するすべての要素のタプルのリストを作成します

>>> [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == 'str_5']
[(5, 5, 'str_5'), (15, 5, 'str_5')]

ここで、そこにない文字列でテストします。

>>> [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == 'str_123']
[]

そうすれば、プレゼンスのテスト、発生のカウント、必要なアイテムの抽出の両方を簡単に行うことができます。

>>> for t in [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == target]:
...    print('index: {}, int: {}, str: "{}"'.format(*t))
... 
index: 7, int: 7, str: "str_7"
index: 13, int: 7, str: "str_7"

他の人が言っているように、あなたはあなたのデータ構造を作り直すことができます。int_xインデックスとして保管していますか?そうしないでください。文字列のリストを使用して列挙します。str_xとint_xの間の単なるマッピングである場合は、辞書を使用してください。

于 2012-08-18T16:15:19.753 に答える