1

与えられた:

A = [['Yes', 'lala', 'No'], ['Yes', 'lala', 'Idontknow'], ['No', 'lala', 'Yes'], ['No', 'lala', 'Idontknow']]

['Yes', X, 'No']A内に存在するかどうかを知りたいのですが、X気にしないものはどこにありますか。

私が試みた:

valid = False
for n in A:
    if n[0] == 'Yes' and n[2] == 'No':
        valid = True

set()は、この種の状況で役立つことを知っています。しかし、これはどのように行うことができますか?これは可能ですか?それとも、元のコードに固執する方が良いですか?

4

4 に答える 4

8

存在を確認したい場合は、次のことができます['Yes', 'No'] in A

In [1]: A = [['Yes', 'No'], ['Yes', 'Idontknow'], ['No', 'Yes'], ['No', 'Idontknow']]

In [2]: ['Yes', 'No'] in A
Out[2]: True

次のケースでは、次のことを試してください。

In [3]: A = [['Yes', 'lala', 'No'], ['Yes', 'lala', 'Idontknow'], ['No', 'lala', 'Yes'], ['No', 'lala', 'Idontknow']]

In [4]: any(i[0]=='Yes' and i[2] == 'No' for i in A)
Out[4]: True

または、少し関数を定義することもできます。

In [5]: def want_to_know(l,item):
   ...:     for i in l:
   ...:         if i[0] == item[0] and i[2] == item[2]:
   ...:             return True
   ...:     return False

In [6]: want_to_know(A,['Yes', 'xxx', 'No'])
Out[6]: True

any(i[0]=='Yes' and i[2] == 'No' for i in A*10000)実際には、変換自体よりも10倍速いようです。

In [8]: %timeit any({(x[0],x[-1]) == ('Yes','No') for x in A*10000})
100 loops, best of 3: 14 ms per loop

In [9]: % timeit {tuple([x[0],x[-1]]) for x in A*10000}
10 loops, best of 3: 33.4 ms per loop

In [10]: %timeit any(i[0]=='Yes' and i[2] == 'No' for i in A*10000)
1000 loops, best of 3: 334 us per loop
于 2013-01-15T07:12:26.883 に答える
3

からへのルックアップ時間が改善されるため、最初にlistを に変換します。setO(n)O(1)

In [27]: A = [['Yes', 'No'], ['Yes', 'Idontknow'], ['No', 'Yes'], ['No', 'Idontknow']]

In [28]: s=set(tuple(map(tuple,A)))

In [29]: s
Out[29]: set([('Yes', 'No'), ('No', 'Idontknow'), ('Yes', 'Idontknow'), ('No', 'Yes')])

In [30]: ('Yes', 'No') in s
Out[30]: True

timeit比較:

%timeit ['Yes', 'No'] in A
1000000 loops, best of 3: 504 ns per loop  

%timeit ('Yes', 'No') in s
1000000 loops, best of 3: 442 ns per loop       #winner

%timeit ['No', 'Idontknow'] in A
1000000 loops, best of 3: 861 ns per loop

%timeit ('No', 'Idontknow') in s
1000000 loops, best of 3: 461 ns per loop       #winner

編集:

最初と最後の要素だけに興味がある場合:

In [69]: A = [['Yes', 'No'], ['Yes', 'Idontknow','hmmm'], ['No', 'Yes'], ['No', 'Idontknow']]

In [70]: s={tuple([x[0],x[-1]]) for x in A} # -1 or 2, change as per your requirement
                                         #or set(tuple([x[0],x[-1]]) for x in A)


In [71]: s
Out[71]: set([('Yes', 'No'), ('Yes', 'hmmm'), ('No', 'Idontknow'), ('No', 'Yes')])

In [73]: ('Yes', 'hmmm') in s
Out[73]: True

timeitとの比較any():

In [77]: %timeit ('Yes', 'hmmm') in s
1000000 loops, best of 3: 428 ns per loop      #winner

In [78]: %timeit any(x[0]=="Yes" and x[-1]=="hmmm" for x in A)
100000 loops, best of 3: 2.87 us per loop
于 2013-01-15T07:07:37.503 に答える
0

セットはリストをサポートしていません。タプルに変換できます。

A = [['Yes', 'No'], ['Yes', 'Idontknow'], ['No', 'Yes'], ['No', 'Idontknow']]
valid = ('Yes', 'No') in {tuple(item) for item in A}

@ IgnacioVazquez-Abramsが述べたように、リストからタプルへの変換はO(n)であるため、パフォーマンスを認識している場合は、他の方法を選択する必要があります。

于 2013-01-15T07:08:04.333 に答える
0

以下は、Set() を使用してそれを行う方法です。

>>> A = Set([('Yes', 'No'), ('Yes', 'Idontknow'), ('No', 'Yes'), ('No', 'Idontknow')])
>>> ('Yes','No') in A
True
>>> 

Set の要素はハッシュ可能である必要があるため、リストではなく Set 要素としてタプルを使用しました。

于 2013-01-15T07:13:34.927 に答える