在Python中合并n个排序元组列表
我有 n 个列表(n<10),每个列表里面都是一些元组,格式是 [(ListID, [(index,value),(index, value),...)]。我想按照 index 来排序,得到下面的结果:
Example Input:
[('A',[(0.12, 'how'),(0.26,'are'),(0.7, 'you'),(0.9,'mike'),(1.9, "I'm fine too")]),
('B',[(1.23, 'fine'),(1.50, 'thanks'),(1.6,'and you')]),
('C',[(2.12,'good'),(2.24,'morning'),(3.13,'guys')])]
Desired Output:
[('A', ( 0.12, 'how')),
('A', ( 0.26, 'are')),
('A', ( 0.7, 'you')),
('A', ( 0.9, 'mike')),
('B',(1.23, 'fine')),
('B',(1.50, 'thanks')),
('B',(1.6,'and you')),
('A', (1.9, "I'm fine too")),
('C',(2.12,'good')),
('C',(2.24,'morning')),
('C',(3.13,'guys'))]
我知道我的代码看起来很糟糕,特别是那些索引 item[0][-1][1],但有没有人能告诉我我哪里做错了?
content = []
max = 0.0
first = True
Done = False
finished = []
while not Done:
for item in flow:
if len(finished) == 4:
Done = True
break
if len(item[1]) == 0:
if item[0] not in finished:
finished.append(item[0])
continue
if first == True:
max = item[1][-1][0]
content.append((item[0], item[1].pop()))
first = False
continue
if item[1][-1][0] > max:
max = item[1][-1][0]
content.append((item[0], item[1].pop()))
content = sorted(content, key=itemgetter(1))
first = True
更新:谢谢大家!
4 个回答
2
在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在程序中使用这些数据。这个过程就像是从冰箱里拿食材,然后用这些食材做饭一样。
当我们获取数据时,可能会遇到一些问题,比如数据的格式不对,或者数据不完整。这就像是你从冰箱里拿到的食材,有可能是坏的,或者缺少了一些必要的东西。
为了避免这些问题,我们可以在获取数据之前,先检查一下这些数据是否符合我们的要求。这样可以确保我们在做饭的时候不会遇到麻烦。
总之,处理数据就像做饭一样,需要仔细检查食材,确保一切都准备好,才能做出美味的菜肴。
data = [(x,id) for (id, xs) in data for x in xs]
data.sort()
for xs,id in data:
print id,xs
A (0.12, 'how')
A (0.26000000000000001, 'are')
A (0.69999999999999996, 'you')
A (0.90000000000000002, 'mike')
B (1.23, 'fine')
B (1.5, 'thanks')
B (1.6000000000000001, 'and you')
A (1.8999999999999999, "I'm fine too")
C (2.1200000000000001, 'good')
C (2.2400000000000002, 'morning')
C (3.1299999999999999, 'guys')
2
(好的,样本数据让问题描述变得更清晰了。答案也相应进行了修改)
第一步:通过反向工程你的当前解决方案来澄清问题描述。
- 有4个不同的数据集,分别标记为A、B、C和D
- 这些数据集包含一系列的2元组,格式为(ListID, elements)
- 每个“elements”条目本身是一个2元组的列表,格式为(index, value)
- 一个空的elements条目表示数据集的结束
- 目标是将这些数据集合并成一个单一的已排序列表,格式为2元组(ListID, (index, value))
第二步:转换输入数据,创建所需格式的单独记录。
为这种情况构建生成器是很有意义的,所以定义一个生成器是合理的。
def get_data(flow, num_data_sets=4):
finished = set()
for list_id, elements in flow:
if list_id in finished:
continue
if not elements:
finished.add(list_id)
if len(finished) == num_data_sets:
break
continue
for element in elements:
yield list_id, element
第三步:使用sorted
来生成所需的有序列表
content = sorted(get_data(flow))
示例用法:
# get_data defined via copy/paste of source code above
# ref_data taken from the revised question
>>> demo_data = [
... ('A', [(1, 2), (3, 4)]),
... ('B', [(7, 8), (9, 10)]),
... ('A', [(0, 0)]),
... ('C', []), # Finish early
... ('C', [('ignored', 'entry')])
... ]
>>> content = sorted(get_data(demo_data))
>>> print '\n'.join(map(str, content))
('A', 0, 0)
('A', 1, 2)
('A', 3, 4)
('B', 7, 8)
('B', 9, 10)
>>> content = sorted(get_data(ref_data), key=itemgetter(1))
>>> print '\n'.join(map(str, content))
('A', 0.12, 'how')
('A', 0.26, 'are')
('A', 0.7, 'you')
('A', 0.9, 'mike')
('B', 1.23, 'fine')
('B', 1.5, 'thanks')
('B', 1.6, 'and you')
('A', 1.9, "I'm fine too")
('C', 2.12, 'good')
('C', 2.24, 'morning')
('C', 3.13, 'guys')
你的解决方案最终会变得杂乱且难以阅读,主要有两个原因:
- 没有使用生成器意味着你没有充分利用内置的排序功能
- 使用索引而不是元组解包会让你很难跟踪每个部分的含义
5
>>> from operator import itemgetter
>>> import pprint
>>> pprint.pprint(sorted(((i,k) for i,j in INPUT for k in j), key=itemgetter(1)))
[('A', (0.12, 'how')),
('A', (0.26000000000000001, 'are')),
('A', (0.69999999999999996, 'you')),
('A', (0.90000000000000002, 'mike')),
('B', (1.23, 'fine')),
('B', (1.5, 'thanks')),
('B', (1.6000000000000001, 'and you')),
('A', (1.8999999999999999, "I'm fine")),
('C', (2.1200000000000001, 'good')),
('C', (2.2400000000000002, 'morning')),
('C', (3.1299999999999999, 'guys'))]
这里主要有两个事情在发生
[(i,k) for i,j in INPUT for k in j]
将输入转换成这个结构
[('A', (0.12, 'how')),
('A', (0.26, 'are')),
('A', (0.7, 'you')),
('A', (0.9, 'mike')),
('A', (1.9, "I'm fine")),
('B', (1.23, 'fine')),
('B', (1.5, 'thanks')),
('B', (1.6, 'and you')),
('C', (2.12, 'good')),
('C', (2.24, 'morning')),
('C', (3.13, 'guys'))]
并且
sorted(L, key=itemgetter(1))
根据每个元素的第二个值对列表进行排序。实际上,这些元素是 (0.12, 'how'), (0.27, 'are') ... 但是在Python中,排序元组时是从左到右的,所以我们不需要额外的工作来从元组中提取单词