Python - 从列表中间开始迭代,然后检查任意一方

时间:2015-05-22 12:24:42

标签: python iteration

真的不确定这适合哪里。说,我有一个清单:

>>>a = [1, 2, 3, 4, 5, 6, 7]

如何以这样的方式迭代它,它将首先检查4,然后是5,然后是3,然后是6,然后是2(对于更大的列表,依此类推)?我只能找到中间的

>>>middle = [len(a)/2 if len(a) % 2 = 0 else ((len(a)+1)/2)]

我真的不确定如何应用这个,我也不确定我的中间方式是最好的方法。我想过抓住两个索引,每次迭代后,添加1并从每个索引中减1,但不知道如何使for循环遵守这些规则。

关于我为什么需要这个;这是用于分析纸牌游戏中的有效游戏,并将从给定手牌的中间牌检查到每一端,直到可以播放有效的牌。

5 个答案:

答案 0 :(得分:7)

您可以继续从列表中间删除:

lst = range(1, 8)
while lst:
    print lst.pop(len(lst)/2)

这不是性能方面的最佳解决方案(从列表中删除项目很昂贵),但它很简单 - 对于简单的游戏来说已经足够了。

编辑:

更高性能稳定的解决方案是生成器,它计算元素位置:

def iter_from_middle(lst):
    try:
        middle = len(lst)/2
        yield lst[middle]

        for shift in range(1, middle+1):
            # order is important!
            yield lst[middle - shift]
            yield lst[middle + shift]

    except IndexError: # occures on lst[len(lst)] or for empty list
        raise StopIteration

答案 1 :(得分:6)

首先,here是一个非常有用的通用实用工具,用于交错两个序列:

def imerge(a, b):
    for i, j in itertools.izip_longest(a,b):
        yield i
        if j is not None:
            yield j

有了这个,你只需要imerge

a[len(a) / 2: ]

reversed(a[: len(a) / 2])

答案 2 :(得分:3)

你也可以玩索引游戏,例如:

>>> a = [1, 2, 3, 4, 5, 6, 7]
>>> [a[(len(a) + (~i, i)[i%2]) // 2] for i in range(len(a))]
[4, 5, 3, 6, 2, 7, 1]

>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> [a[(len(a) + (~i, i)[i%2]) // 2] for i in range(len(a))]
[4, 5, 3, 6, 2, 7, 1, 8]

答案 3 :(得分:1)

这是一个为任何给定长度产生交替索引的生成器。它可能会改进/缩短,但它的工作原理。

def backNforth(length):
    if length == 0:
        return
    else:
        middle = length//2
        yield middle

        for ind in range(1, middle + 1):
            if length > (2 * ind - 1):
                yield middle - ind
            if length > (2 * ind):
                yield middle + ind 

# for testing:
if __name__ == '__main__':
    r = range(9)
    for _ in backNforth(len(r)):
        print(r[_])

使用它,您可以按照您想要的顺序生成项目列表:

a = [1, 2, 3, 4, 5, 6, 7]
a_prime = [a[_] for _ in backNforth(len(a))]

答案 4 :(得分:1)

除了中间元素之外,我还需要它们的索引。我发现Wasowski的答案非常有帮助,并对其进行了修改:

def iter_from_middle(lst):
    index = len(lst)//2
    for i in range(len(lst)):
        index = index+i*(-1)**i
        yield index, lst[index]

>>> my_list = [10, 11, 12, 13, 14, 15]
>>> [(index, item) for index, item in iter_from_middle(my_list)]
[(3, 13), (2, 12), (4, 14), (1, 11), (5, 15), (0, 10)]