如何只对python循环中的第一项做某事?
Posted
技术标签:
【中文标题】如何只对python循环中的第一项做某事?【英文标题】:How to do something only to the first item within a loop in python? 【发布时间】:2014-01-27 04:44:09 【问题描述】:我想做一些与列表中的第一项不同的事情。这样做最pythonic的方式是什么?
for item in list:
# only if its the first item, do something
# otherwise do something else
【问题讨论】:
使用处理第一个项目后更改的标志。 【参考方案1】:几个选择,按 Pythonicity 降序排列:
for index, item in enumerate(lst): # note: don't use list
if not index: # or if index == 0:
# first item
else:
# other items
或者:
first = True
for item in lst:
if first:
first = False
# first item
else:
# other items
或者:
for index in range(len(lst)):
item = lst[i]
if not index:
# first item
else:
# other items
【讨论】:
使用enumerate
优于其他几个选项的一个优点是,被迭代的对象是否支持索引并不重要。
我喜欢枚举,但我不知道我是否会使用if not index
。 if index==0
更明确。
@adsmith:PEP 8 另有说明。并且在标准库中有恰好if not index:
的示例。
所有变体都需要 if 在循环体中。非常低效
@volcano:真的吗?你测试过吗?因为通常情况下,至少在 CPython 中,if myint:
的成本比在迭代器上调用 next
的成本低几个数量级,所以你几乎无法测量它。如果您有一个“非常低效”的具体示例,请发布数据。【参考方案2】:
您可以使用 iter() 在列表上创建一个迭代器,然后对其调用 next() 以获取第一个值,然后循环其余的值。我发现这是处理文件的一种非常优雅的方式,其中第一行是标题,其余的是数据,即
list_iterator = iter(lst)
# consume the first item
first_item = next(list_iterator)
# now loop on the tail
for item in list_iterator:
print(item)
【讨论】:
解释有点不对劲——你没有将列表转换为迭代器,而是在列表上创建迭代器。因效率和优雅而受到赞誉 好点,我已经编辑澄清。另外我喜欢调用 iter(iter(list)) 仍然返回内部 所以你不需要知道 lst 是列表对象还是 list_iterator (或其他可迭代对象)【参考方案3】:do_something_with_first_item(lst[0])
for item in lst[1:]:
do_something_else(item)
或者:
is_first_item = True
for item in lst:
if is_first_item:
do_something_with_first_item(item)
is_first_item = False
else:
do_something_else(item)
不要使用list
作为变量名,因为这会影响内置函数list()
。
jonrsharpe 的答案中基于enumerate
的解决方案优于此。您可能应该改用它。
【讨论】:
【参考方案4】:使用处理第一个项目后更改的标志。例如:
first = True
for item in my_list:
if first:
# Processing unique to the first item
first = False
else:
# Processing unique to other items
# Shared processing
您也可以只处理第一项:
first = my_list.pop(0)
# Process first
for item in my_list:
# Process item
# Add the first item back to the list at the beginning
my_list.insert(0, first)
【讨论】:
+!对于.pop()
,老实说,这是这里最好、最干净的解决方案。【参考方案5】:
jonrsharpe 使用enumerate
的第一个版本简洁明了,适用于所有可迭代对象:
for index, item in enumerate(lst):
if not index:
do_something_with_first_item(item)
else:
do_something_else(item)
senshin 使用lst[0]
和lst[1:]
的第一个解决方案更加简单,但仅适用于序列:
do_something_with_first_item(lst[0])
for item in lst[1:]:
do_something_else(item)
您可以通过直接使用迭代器获得两全其美:
it = iter(lst)
do_something_with_first_item(next(it))
for item in it:
do_something_else(item)
但是,尽管它是两全其美的,但实际上并没有那么简单。如果您知道自己有一个迭代器(因此您可以跳过第一行),或者您无论如何都需要一个迭代器来执行itertools
和genexpr 和类似的东西(所以你是已经要写第一行了)。在其他情况下是否值得做更多的是风格问题。
【讨论】:
我认为对于最后一种方法,您不必知道是否有迭代器。我做了一个快速检查并在迭代器上调用 iter() 似乎返回了原始迭代器 - 即 iter(iter([1,2,3])) 和 iter([1,2,3]) 都返回一个 迭代原始列表。所以我会在每种情况下都使用这种方法——第一种是干净的,但会在循环的每次迭代中测试索引,秒需要一个可索引的对象。 @user2981639: 是的,如果iter(it)
是一个迭代器,它肯定会返回it
——也就是说,事实上,它是迭代器定义的一部分。关键是如果你知道它是一个迭代器,你可以跳过第一行,这是最简单的解决方案;如果你有一个序列,或者不知道你有什么样的可迭代,你不能跳过第一行,所以它可能不是最简单的以上是关于如何只对python循环中的第一项做某事?的主要内容,如果未能解决你的问题,请参考以下文章
使用Apache-beam在Python中删除字典中的第一项[重复]