私は約20000のリストからなるリストがあります。各リストの3番目の要素をフラグとして使用します。少なくとも1つの要素のフラグが0である限り、私はこのリストでいくつかの操作をしたいです、それはのようなものです:
my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]
最初は、すべてのフラグは0です。少なくとも1つの要素のフラグが0かどうかを確認するには、whileループを使用します。
def check(list_):
for item in list_:
if item[2] == 0:
return True
return False
check(my_list)
がTrue
を返した場合、私は自分のリストで作業を続けます。
while check(my_list):
for item in my_list:
if condition:
item[2] = 1
else:
do_sth()
実際には、my_listの要素を繰り返し処理するときに削除したかったのですが、繰り返し処理するときに項目を削除することはできません。
元のmy_listにはフラグがありませんでした。
my_list = [["a", "b"], ["c", "d"], ["e", "f"], .....]
繰り返したときに要素を削除できなかったので、これらのフラグを発明しました。しかしmy_list
にはたくさんの項目が含まれており、while
ループはそれぞれのfor
ループでそれらすべてを読み取ります。そしてそれは多くの時間がかかります!何か提案はありますか?
ここでの最良の答えは all()
を使うことです。これはこの状況のための組み込み関数です。これを ジェネレータ式 と組み合わせて、必要な結果をきれいにそして効率的に生成します。例えば:
>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
>>> all(item[2] == 0 for item in items)
True
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]]
>>> all(item[2] == 0 for item in items)
False
そして、彼のフィルタの例では、リストの内包表記:
>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]
少なくとも1つの要素が0であることを確認したい場合は、もっと読みやすい any()
を使用することをお勧めします。
>>> any(item[2] == 0 for item in items)
True
このようにitertoolsの時間を使うことができます、あなたのステートメントを失敗させる条件が満たされるとそれは停止します。反対の方法はドロップスルーになります
for x in itertools.takewhile(lambda x: x[2] == 0, list)
print x
リスト内のいずれかの項目が条件に違反していないかどうかを確認したい場合は、all
を使用します。
if all([x[2] == 0 for x in lista]):
# Will run if all elements in the list has x[2] = 0 (use not to invert if necessary)
一致しないすべての要素を削除するには、filter
を使用します。
# Will remove all elements where x[2] is 0
listb = filter(lambda x: x[2] != 0, listb)
この方法はall()
を使うよりももう少し柔軟です。
my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
all_zeros = False if False in [x[2] == 0 for x in my_list] else True
any_zeros = True if True in [x[2] == 0 for x in my_list] else False
itertools.ifilter
を使用する別の方法。これにより、真実性とプロセスがチェックされます(lambda
を使用)
サンプル-
for x in itertools.ifilter(lambda x: x[2] == 0, my_list):
print x