【发布时间】:2017-06-13 09:17:53
【问题描述】:
这是一个问题是What's the most Pythonic way to identify consecutive duplicates in a list?的扩展。
假设你有一个元组列表:
my_list = [(1,4), (2,3), (3,2), (4,4), (5,2)]
然后按每个元组的最后一个值对其进行排序:
my_list = sorted(my_list, key=lambda tuple: tuple[1])
# [(3,2), (5,2), (2,3), (1,4), (4,4)]
然后我们有两个连续的运行(查看每个元组中的最后一个值),即[(3,2), (5,2)] 和[(1,4), (4,4)]。
反转每次运行(不是其中的元组)的pythonic方法是什么,例如
reverse_runs(my_list)
# [(5,2), (3,2), (2,3), (4,4), (1,4)]
这可以在生成器中完成吗?
更新
我注意到示例列表可能不清楚。所以改为考虑:
my_list = [(1,"A"), (2,"B"), (5,"C"), (4,"C"), (3,"C"), (6,"A"),(7,"A"), (8,"D")]
reverse_runs 的理想输出在哪里
[(7,"A"), (6,"A"), (1,"A"), (2,"B"), (3,"C"), (4,"C"), (5,"C"), (8,"D")]
为了明确术语,我采用了“运行”的用法,用于描述 TimSort,这是 Python 的排序函数所基于的 - 为它(排序函数)提供了安全性。
因此,如果您对集合进行排序,如果集合是多面的,那么只有 指定的维度会在 和上排序,如果两个元素是 对于指定的维度相同,它们的顺序将不会改变。
因此以下函数:
sorted(my_list,key=lambda t: t[1])
产量:
[(1, 'A'), (6, 'A'), (7, 'A'), (2, 'B'), (5, 'C'), (4, 'C'), (3, 'C'), (8, 'D')]
"C"(即(5, 'C'), (4, 'C'), (3, 'C'))上的运行不会受到干扰。
因此,总而言之,来自尚未定义的函数 reverse_runs 的所需输出:
1.) 按元组的最后一个元素对元组进行排序
2.) 保持第一个元素的顺序,反向运行在最后一个元素上
理想情况下,我希望在生成器函数中使用此功能,但这(目前对我而言)似乎是不可能的。
因此可以采取以下策略:
1.) 通过sorted(my_list, key=lambda tuple: tuple[1])按最后一个元素对元组进行排序
2.) 当后续元组 (i+1) 与 (i) 中的最后一个元素不同时,识别每个元组中最后一个元素的索引。即识别运行
3.) 制作一个空列表
4.) 使用拼接运算符,获取、反转并将每个子列表附加到空列表中
【问题讨论】:
-
连续运行两次是什么意思?
-
@WillemVanOnsem 在排序键中重复。
-
我认为他将运行定义为每个元组中的第二个元素相等...所以 [(1,2), (2,2), (3,2)] 是运行三..
-
@not_a_robot 正确
-
也许是一个相关的答案:How do I use Python's itertools.groupby?
标签: python algorithm list generator timsort