我目前的解决方案指针是
还有另一种更好的方法来解决这一挑战吗?
修改
@Glenn:好的反对意见。 我没有想到这一点,因为我经历的列表没有以我想象的方式排序。@ THC4k:谢谢你的解决方案。我学习了chain.from_iterable
@Mike DeSimone:嗯测试了你的解决方案,但出了点问题,也许我错过了一些东西,...@Jamie和Odomontois: 感谢您指出更详细的
我的目标
我正在伪造一个小算法来转换任务列表 - 对/元组:(开始,停止) - 到一个简化的任务列表,重叠的任务合并在一起。
一个例外:当一个事件与另一个事件完全重叠时,我的算法失败(s1 s2 e2 e1)
详细说明:
示例,只是字符串表示时间的可读性
taskList = [(9:00,10:00),(9:30,11:00),(11:00,12:30),(13:30,14:00),(14:00,18:00)]
最后的结果:
result = [(9:00,12:30), (13:30,18:00)]
现在我的想法是,当我以我质疑的方式重新排列'taskList'时
taskListT1 = [(9:00,),(10:00,9:30),(11:00,11:00),(12:30,13:30),(14:00,14:00),(18:00,)]
现在我可以消除那些a>; b:
的元组(a,b)taskListT2 = [(9:00,),(12:30,13:30),(18:00,)]
并转换回来:
result = [(9:00,12:30), (13:30,18:00)]
答案 0 :(得分:1)
嗯,这是收益率的解决方案:
# transform forwards
def transform_pairs( lst ):
it = iter(lst)
a,last = next(it)
yield [a]
for a,b in it:
yield last, a
last = b
yield [last]
将列表转换回来应该看起来非常相似,但我会把它留给读者。
这是另一个可以在两个方向上转换的稍微复杂的一个。它会产生元组,因为固定长度的列表是 lame 。
from itertools import chain
def transform( iterable, offset):
it = chain.from_iterable(iterable) # turn it back to one long list.
if offset:
yield next(it), # the trailing `,` makes this a tuple.
for item in it:
try:
x = next(it)
except StopIteration: # there is no 2nd item left
yield item,
else:
yield item, x # yield the pair
print list(transform(transform([[1,2],[3,4],[5,6],[7,8]], True), False))
答案 1 :(得分:1)
选择'另一种更好的方式'选项(甚至可以使OP的异常正确):
def compress_task_list(tasks):
tasks = list(tasks)
tasks.sort(key=lambda item: item[0]) # make sure list is in order by start time
result = []
first_start = tasks[0][0]
final_stop = tasks[0][1]
for start, stop in tasks[1:]:
if start > final_stop:
result.append((first_start, final_stop))
first_start = start
final_stop = stop
elif stop > final_stop:
final_stop = stop
result.append((first_start, final_stop))
return tuple(result)
if __name__ == '__main__':
import unittest
class Test_Compress_Task_List(unittest.TestCase):
def test_01(self):
"completely separate"
initial = ((8.0, 9.5), (10.0, 12.0), (13.0, 15.5), (16.0, 17.0))
expected = ((8.0, 9.5), (10.0, 12.0), (13.0, 15.5), (16.0, 17.0))
self.assertEqual(compress_task_list(initial), expected)
def test_02(self):
"end equals start"
initial = ((8.0, 9.5), (9.5, 12.0), (13.0, 15.5), (15.5, 17.0))
expected = ((8.0, 12.0), (13.0, 17.0))
self.assertEqual(compress_task_list(initial), expected)
def test_03(self):
"end equals start (with more empty times)"
initial = ((8.0, 8.5), (8.5, 10.0), (10.25, 12.0), (12.5, 13.75), (13.75, 15.0), (15.25, 16.0), (16.0, 17.0))
expected = ((8.0, 10.0), (10.25, 12.0), (12.5, 15.0), (15.25, 17.0))
self.assertEqual(compress_task_list(initial), expected)
def test_04(self):
"out of order, cross-overs, and tasks completely inside other tasks"
initial = ((8.0, 8.5), (8.0, 10.0), (10.25, 12.0), (10.0, 11.5), (13.0, 15.5), (14.0, 15.0), (16.0, 17.0))
expected = ((8.0, 12.0), (13.0, 15.5), (16.0, 17.0))
self.assertEqual(compress_task_list(initial), expected)
unittest.main()
请记住,这是Python,可读性很重要。 ;)
答案 2 :(得分:0)
这很有效,但感觉Pythonic就在那里:
l = [[1,2], [3,4], [5,6], [7,8]]
o = []
last = []
for a, b in l:
o.append(last+[a])
last = [b]
o.append(last)
print o
打印
[[1], [2, 3], [4, 5], [6, 7], [8]]
这个机构也有效:
o = [[l[0][0]]]
for i in range(len(l)-1):
o.append([l[i][1], l[i+1][0]])
o.append([l[-1][1]])
答案 3 :(得分:0)
l = [[1,2], [3,4], [5,6], [7,8]]
m = [([] if i==0 else [l[i-1][1]] )+([] if i==len(l) else [l[i][0]]) for i in xrange(len(l)+1)]
答案 4 :(得分:0)
你的意思是:
pairs = [[1,2], [3,4], [5,6], [7,8]]
print pairs, '->',
transformed = ([[pairs[0][0]]]+
[[a,b] for a,b in zip(
(second for first, second in pairs[:-1]),
(first for first, second in pairs[1:]))]+
[[pairs[-1][-1]]]
)
print transformed
""" Output:
[[1, 2], [3, 4], [5, 6], [7, 8]] -> [[1], [2, 3], [4, 5], [6, 7], [8]]
"""
答案 5 :(得分:0)
这是一个可以使用生成器或列表输入的生成器,因此您不必将所有内容保存在内存中:
def shift_pairs(inPairs):
lastPair = None
for pair in inPairs:
if lastPair:
yield [lastPair[1], pair[0]]
else:
yield [pair[0]]
lastPair = pair
yield [lastPair[1]]
我必须指出,在Python中,短,固定长度的列表通常以元组的形式完成:
def shift_pairs(inPairs):
lastPair = None
for pair in inPairs:
if lastPair:
yield (lastPair[1], pair[0])
else:
yield (pair[0],)
lastPair = pair
yield (lastPair[1],)