如何只对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 indexif 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循环中的第一项做某事?的主要内容,如果未能解决你的问题,请参考以下文章

pytest 如何在第一项断言失败后不退出 for 循环

使用Apache-beam在Python中删除字典中的第一项[重复]

如何排除 flexbox 包装中的第一项?

如何在IOS中读取多个数组中的第一项

如果表单未绑定,如何选择 MS Access 组合框中的第一项

Extjs 4.1 如何选择组合中的第一项