Skip to content Skip to sidebar Skip to footer

Python: Get Items From List Between 2 Known Items

I'm looking for a way to get all items from a python list that are between 2 items. The algorithm must warp through the whole array. For instance: I have a string like 'Mo-Fr' and

Solution 1:

A simple solution is to double the days_order list so that it contains all rotations of the weekdays:

>>>days_order = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'] * 2

then get the start/end indexes like this:

>>>string = 'Fr-Mo'>>>days = string.split('-')>>>start = days_order.index(days[0])>>>end = days_order.index(days[1], start + 1) + 1

and finally build the list of days like this:

>>> [days_dict[day] fordayin days_order[start:end]]
['Freitag', 'Samstag', 'Sonntag', 'Montag']

Solution 2:

A simple way to do this is to use two copies of the days_order list, and then slice that list in two steps.

days_order = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']
days_dict = {
    'Mo' : 'Montag',
    'Di' : 'Dienstag',
    'Mi' : 'Mittwoch',
    'Do' : 'Donnerstag',
    'Fr' : 'Freitag',
    'Sa' : 'Samstag',
    'So' : 'Sonntag',
}

def daylist(days):
    first, last = days.split('-')

    days = days_order * 2
    i = days.index(first)
    days = days[i:]

    i = days.index(last)
    days = days[:i+1]
    return [days_dict[s] for s in days]

s = "Mo-Fr"print s, daylist(s)

s = "Fr-Mo"print s, daylist(s)

output

Mo-Fr ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag']
Fr-Mo ['Freitag', 'Samstag', 'Sonntag', 'Montag']

The above code just returns a single day if the two given items are identical. If instead a full cycle of days is wanted in such cases then ekhumoro's algorithm can be used.

Here's my version:

days_order = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']
days_dict = {
    'Mo' : 'Montag',
    'Di' : 'Dienstag',
    'Mi' : 'Mittwoch',
    'Do' : 'Donnerstag',
    'Fr' : 'Freitag',
    'Sa' : 'Samstag',
    'So' : 'Sonntag',
}

def daylist(days):
    first, last = days.split('-')

    days = days_order * 2
    i = days.index(first)
    j = days.index(last, i + 1)
    return [days_dict[s] for s in days[i:j+1]]    

s = "Mo-Fr"print s, daylist(s)

s = "Fr-Mo"print s, daylist(s)

s = "Di-Di"print s, daylist(s)

s = "Do-Mi"print s, daylist(s)

output

Mo-Fr ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag']
Fr-Mo ['Freitag', 'Samstag', 'Sonntag', 'Montag']
Di-Di ['Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag', 'Montag', 'Dienstag']
Do-Mi ['Donnerstag', 'Freitag', 'Samstag', 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch']

And here's another approach, this time using modular arithmetic, as suggested in a comment by David Lemon:

days_short = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So']
days_long = [
    'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 
    'Freitag', 'Samstag', 'Sonntag'
]

def daylist(days):
    first, last = days.split('-')

    i = days_short.index(first)
    j = days_short.index(last)
    if j <= i:
        j += 7return [days_long[k % 7] for k in range(i, j+1)]

s = "Mo-Fr"print s, daylist(s)

s = "Fr-Mo"print s, daylist(s)

s = "Di-Di"print s, daylist(s)

s = "Do-Mi"print s, daylist(s)

Solution 3:

Here is a function for this:

def AtoB (string, lst):
    a, b = string.split("-")
    sublist = []
    i = lst.index(a)
    while lst[i] != b:
        sublist.append(lst[i])
        i+=1
        i%=len(lst)
    return sublist + [b]

Use it like:

days = AtoB(string, days_order)

Solution 4:

Loop the days_order just once:

for from_to in ['Di-Sa', 'Fr-Mi', 'Di-Di']:

    start_matched, collect_for_buffer = False, True
    head, buffer, tail = [], [], []
    _from, _to = from_to[-2:], from_to[:2]

    for x in days_order:

        if _from == x:
            tail.append(days_dict[x])
            if start_matched isFalse:
                tail = buffer + tail
            start_matched = Falseelse:
            if start_matched isFalseand collect_for_buffer:
                buffer.append(days_dict[x])

        if _to == x or start_matched:
            start_matched = True
            head.append(days_dict[x])

    print from_to, head + tail

et voila

Di-Sa ['Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag']
Fr-Mi ['Freitag', 'Samstag', 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch']
Di-Di ['Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag', 'Montag', 'Dienstag']

Post a Comment for "Python: Get Items From List Between 2 Known Items"