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"