在迭代器中的最后一项的情况下跳过语句

Skip statements in case of last item in iterator

我想为字典中的最后一个键值对跳过 for 循环中的一些语句。

让我们假设下一个片段是真正的程序:

a = { 'a': 1, 'b': 2, 'c': 3 } # I don't know the exact values, so can't test on them
for key, value in a.iteritems():
    # statements always to be performed

    # statements I want to skip when the current key, value pair is the last unprocessed pair in the dict.

    # maybe some more statements not to be skipped (currently not forseen, but might be added in the future)

# other statements in the program

应该是简单的东西,但是我找不到。

好的,我可以使用 while 循环来编写它:

stop = False
b = a.iteritems()
next_key, next_value = b.next()
while True:
    key, value = next_key, next_value
    # do stuff which should be done always

    try:
        next_key, next_value = b.next()
    except StopIteration:
        stop = True
    else:
        # do stuff which should be done for everything but the last pair

    # the future stuff which is not yet forseen.

    if stop:
        break

但我认为这是丑陋的代码,因此我寻找一种在 for 循环中执行此操作的好方法。 这可能吗?

哦,是的:它需要为 python 2.7 工作(并且 python 2.5 将是一个奖励)因为那是我工作中的 python 版本(主要是 python 2.7).

首先,普通字典是无序的,所以你需要使用 OrderedDict 或元组数组。

其次,为什么不排除循环集合中的最后一个元素。

import collections

a = OrderedDict()
# add stuff to a

for key, value in a.items()[:-1]:
    # do something

因为它必须在任何可迭代对象上工作,所以你不能依赖 len

为了能够使用 for 循环,我会创建一个辅助生成器函数来延迟 yield 直到它知道它是否是最后一个元素。

如果是最后一个元素,则 returns True + 键/值,否则 False + 键/值

概念验证:

a = { 'a': 1, 'b': 2, 'c': 3 }

def delayed_iterator(a):
    previous_v = None
    while True:
        v = next(a,None)
        if not v:
            yield True, previous_v
            break
        else:
            if previous_v:
                yield False, previous_v
            previous_v = v


for is_last, v in delayed_iterator(iter(a)):  # with iter, we make sure that it works with any iterable
    print(is_last,v,a[v])

输出为:

False a 1
False b 2
True c 3

您可以使用 itertools.islice 获取除最后一项之外的所有项目:

from itertools import islice

a = { 'a': 1, 'b': 2, 'c': 3 }
for key, value in islice(a.iteritems(), len(a)-1 if a else None):
    ...

三元条件有助于处理 len(a)-1 给出否定结果的情况,即字典为空。

python 字典中没有 "first" 或 "last" 键,因为它在遍历时不保留其元素的插入顺序。

但是您可以使用 OrderedDict 并像这样识别最后一个元素:

import collections

a = collections.OrderedDict()
a['a'] = 1
a['b'] = 2
a['c'] = 3

for key, value in a.items():
    if(key != list(a.items())[-1][0]):
        # statements I want to skip when the current key, value pair is the last unprocessed pair in the dict.