Это можно сделать несколькими разными способами. Существует оптимальное решение, которое приближает вас к цели, насколько это возможно, но вы хотите, чтобы список воспроизведения был случайным, и все, чтобы в конечном итоге получить воспроизведение, поэтому что-то вроде этого должно сработать ...
from random import randint, shuffle
# create some tracks between 2-4 minutes for testing
tracks = { "Track {0}".format(i): "{0}:{1:02d}".format(randint(2, 3), randint(0, 59)) for i in range(20) }
print(tracks)
# covert to a list of elements with the time in seconds
def min_to_sec(x):
m, s = x.split(":")
return int(m) * 60 + int(s)
items = [ (k, min_to_sec(v)) for k, v in tracks.items() ]
# randomise
shuffle(items)
# a function that sums the lengths from an index position till
# it exceeds the max.
def select_tracks(items, index, max_seconds):
total = 0
selected = []
for name, length in items[index:]:
if total + length > max_seconds:
break
total += length
selected.append(name)
return total, selected
# run at each start position
results = [ select_tracks(items, i, 30*60) for i in range(len(items)) ]
# if we sort and select the last that is the best for this randomised order
results.sort()
playlist = results[-1]
print("\nPlaylist: {0} ({1} seconds)".format(", ".join(playlist[1]), playlist[0]))
Вывод:
{'Track 0': '2:51', 'Track 1': '2:25', 'Track 2': '3:21', 'Track 3': '3:03', 'Track 4': '3:22', 'Track 5': '3:03', 'Track 6': '3:32', 'Track 7': '3:58', 'Track 8': '3:40', 'Track 9': '2:16', 'Track 10': '3:32', 'Track 11': '3:52', 'Track 12': '3:03', 'Track 13': '2:37', 'Track 14': '2:45', 'Track 15': '2:57', 'Track 16': '3:19', 'Track 17': '3:06', 'Track 18': '2:15', 'Track 19': '3:05'}
Playlist: Track 5, Track 14, Track 18, Track 9, Track 8, Track 17, Track 10, Track 19, Track 2, Track 0 (1794 seconds)