我想优化。
connection = get_db_connection()
for item in my_iterator:
push_item_to_db(item, connection)
缺点:
get_db_connection()
很慢。如果my_iterator
为空,那么我想避免调用它。
connection = None
for item in my_iterator:
if connection is None:
connection = get_db_connection()
push_item_to_db(item, connection)
缺点:
如果my_iterator
中有100k项,那么if connection is None
会被调用100k次(尽管只需要一次)。我想避免这种情况。
get_db_connection()
if connection is None:
。有什么想法吗?
答案 0 :(得分:5)
您可以执行以下操作:
connection = None
for item in my_iterator:
if connection is None:
connection = get_db_connection()
push_item_to_db(item, connection)
简单的解决方案。不需要过度思考它。即使有100k的操作,x is None
只是一个参考比较,只需要一个Python操作码。与每次插入时发生的完整tcp往返+磁盘写入相比,您真的不需要优化它。
答案 1 :(得分:2)
我不是Python的专家,但我会做这样的事情:
def put_items_to_database (iterator):
try:
item = next(iterator)
# We connect to the database only after we
# know there at least one element in the collection
connection = get_db_connection()
while True:
push_item_to_db(item, connection)
item = next(iterator)
except StopIteration:
pass
这可能是因为性能与数据库绑定在一起。然而问题是如何找到一种方法来避免做不必要的工作,以上是一种精确控制迭代过程中发生的事情的基本方法。
其他解决方案在某种程度上“更简单”,但另一方面,我认为这个解决方案更明确,并遵循最不惊讶的原则。
答案 2 :(得分:2)
for item in my_iterator:
# First item (if any)
connection = get_db_connection()
push_item_to_db(item, connection)
for item in my_iterator:
# Next items
push_item_to_db(item, connection)
答案 3 :(得分:1)
这没有while True
循环。
try:
next(my_iterator)
connection = get_db_connection()
push_item_to_db(item, connection)
except StopIteration:
pass
for item in my_iterator:
push_item_to_db(item, connection)
如果您知道迭代器永远不会返回None
(或任何其他唯一对象),您可以利用next()
的默认值:
if next(my_iterator, None) is not None:
connection = get_db_connection()
push_item_to_db(item, connection)
for item in my_iterator:
push_item_to_db(item, connection)
如果您无法保证迭代器永远不会返回的值,则可以使用标记。
sentinel = object()
if next(my_iterator, sentinel) is not sentinel:
connection = get_db_connection()
push_item_to_db(item, connection)
for item in my_iterator:
push_item_to_db(item, connection)
使用itertools.chain()
:
from itertools import chain
for first_item in my_iterator:
connection = get_db_connection()
for item in chain([first_item], my_iterator):
push_item_to_db(item, connection)
答案 4 :(得分:-1)
您可以在代码的整个部分之前检查迭代器计数
if (len(my_iterator)>0):
connection = get_db_connection()
for item in my_iterator:
push_item_to_db(item, connection)