Python - iteration starts from the middle of the list and then checked on each side

Not really sure where this fits. Let's say I have a list:

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

How can I repeat it so that it first checks 4, then 5, then 3, then 6, then 2 (and so on for large lists)? I could only work out a middle that

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

I'm really not sure how to apply this, and I'm not sure that my way of developing the middle is the best way. I thought about capturing two indexes after each iteration, adding 1 and subtracting 1 from each corresponding index, but I have no idea how to get the for loop to follow these rules.

As for why I need it; he is to analyze the actual game in the card game and will check from the middle card of this hand to each end until a valid card is played.

+4
source share
4 answers

You can simply remove from the middle of the list:

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

This is not the best solution in terms of performance (removing an item from the list is expensive), but it's simple - good enough for a simple game.

EDIT:

A more robust performance solution would be a generator that calculates the position of an element:

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
+6
source

Firstly, it is a very useful universal utility for alternating two sequences:

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

you just need imerge

a[len(a) / 2: ]

with

reversed(a[: len(a) / 2])
+6
source

, :

>>> 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]
+2

, . , /, .

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[_])

Using this, you can simply do this to create a list of elements in the order you want:

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

Source: https://habr.com/ru/post/1589430/


All Articles