Pythonで大きなリストからアイテムを選別する最も効率的な方法(メモリとCPUの観点から)は何でしょうか? これは良い方法ですか?
a = range(0,100000)
a[:] = [item for item in a if item > 10]
ここでの数字はほんの一例です。次の場合もあります。
a = ["my", "very", "big", "list"]
a[:] = [item for item in a if item.startswith("b")]
Pythonで大きなリストからアイテムを選別する最も効率的な方法(メモリとCPUの観点から)は何でしょうか? これは良い方法ですか?
a = range(0,100000)
a[:] = [item for item in a if item > 10]
ここでの数字はほんの一例です。次の場合もあります。
a = ["my", "very", "big", "list"]
a[:] = [item for item in a if item.startswith("b")]
Python には、この目的のために特別に作成されたジェネレーター関数があります。こちらのドキュメントを参照してください。の使用range
(ドキュメントxrange
では、ジェネレーターを返すの使用が推奨されています)以外は、実装は完全に問題ありません。
ドキュメントには次の例があります。
# Build and return a list
def firstn(n):
num, nums = 0, []
while num < n:
nums.append(num)
num += 1
return nums
sum_of_first_n = sum(firstn(1000000))
それは多くのスペースを無駄にします。したがって、ドキュメントでは、代わりに次のようなことを行うことをお勧めします。
# Using the generator pattern (an iterable)
class firstn(object):
def __init__(self, n):
self.n = n
self.num, self.nums = 0, []
def __iter__(self):
return self
def next(self):
if self.num < self.n:
cur, self.num = self.num, self.num+1
return cur
else:
raise StopIteration()
sum_of_first_n = sum(firstn(1000000))
実際にリストが必要な場合 (そして元のリストを適切な場所に置き換えたい場合) は、おそらく純粋な python を使用した場合よりもはるかに優れているとは言えません。ただし、多くの場合、これは必要ありません。多くの場合、反復可能なオブジェクトだけが必要です。
generator = (item for item in a if item > 10)
for item in generator:
...
これによりメモリ効率が向上し、パフォーマンスはほぼ同じになります。
filter
またはgenerators
ここで使用できます
発生器
>>> data = [10, 20, 4, 4, 11, 13.4]
>>> custom_filter = (i for i in data if i > 10)
>>> [j for j in custom_filter]
[20, 11, 13.4]
>>>
フィルター
>>> data = [10, 20, 4, 4, 11, 13.4]
>>> custom_filter = filter(lambda x: x > 10, data)
>>> custom_filter
[20, 11, 13.4]
>>>