Python中合并二维元组列表并进行排序

7
更新:列表中的项是字符串,我编辑了列表以显示它们。
我有3个不同的列表,比如:
Section = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5')] 
Page = [('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5')]
Titles = [('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

我希望将它们结合起来,例如:
Combined_List = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5'),
                 ('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5'),  
                 ('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

或任何其他形式,使我能够按照标题为“sections”的列表中的数字进行排序。

在这种情况下,它将是

  Sorted_list = [('1', '1', '1', '1.1', '1.2', '1.2', '2', '2.2', '3', '3.2', '3.5'), 
                 ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'),
                 ('General', 'More', 'Another', 'Info', 'Titles', 'List', 'Info', 'Section', 'Here', 'Of', 'Strings')

我需要这样做,以便最终可以按部分导出排序列表到Excel。如果您能想到更好的显示/格式,请分享!
3个回答

2

您可以:

from itertools import chain

tuples = zip(map(float, list(chain(*Section))), 
             list(chain(*Page)), 
             list(chain(*Title)))

zip(*sorted(tuples, key=lambda x: x[0]))

Out[232]:
[(1.0, 1.0, 1.0, 1.1, 1.2, 1.2, 2.0, 2.2, 3.0, 3.2, 3.5),
 ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'),
 ('General',
  'More',
  'Another',
  'Info',
  'Titles',
  'List',
  'Info',
  'Section',
  'Here',
  'Of',
  'Strings')]

在这里,您首先需要展开三个列表(list(chain(*L))的作用),并使用zip将它们打包成元组。可以尝试输入“元组”来查看其外观。
接下来,在第二行代码中,您可以根据所需的元组元素应用排序。然后对结果进行解包。

我忘记在原始代码中包含列表是由字符串填充的。我已经更新了帖子以显示这一点。我尝试了你的方法,然后打印了元组的值和代码中的第二行。它们分别返回<zip object at 0x000000000B0E2488>和<zip object at 0x000000000B0E2448>。这些是内存中的位置,对吗?这是因为它们实际上是字符串吗? - Jstuff
我更新了我的答案,考虑到你有字符串这一事实。 - Colonel Beauvel
当我打印列表时,仍然会得到<zip object at 0x000000000B84F848> <zip object at 0x000000000B84F708>。不确定为什么... - Jstuff
我猜这是由于Python版本的问题...什么会先返回tuples?列表?尝试用list()zip包装起来。 - Colonel Beauvel
在 Python 3 中,zip 函数返回一个迭代器。 - ayhan

2

请尝试这个:

Section = [('1', '1.1', '1.2'), ('1', '2', '2.2', '3'), ('1', '1.2', '3.2', '3.5')] 
Page = [('1', '1', '3'), ('1', '2', '2', '2'), ('1', '2', '3', '5')]
Titles = [('General', 'Info', 'Titles'), ('More', 'Info', 'Section', 'Here'), ('Another', 'List', 'Of', 'Strings')]

# Flat a list of tuples into a list
l1 = [item for sublist in Section for item in sublist]
l2 = [item for sublist in Page for item in sublist]
l3 = [item for sublist in Titles for item in sublist]

# Python2, `zip` returns a list of tuples
#result = zip(*sorted(zip(l1, l2, l3), key=lambda x:float(x[0])))

# Python3, `zip` returns an iterator of tuples
result = list(zip(*sorted(zip(l1, l2, l3), key=lambda x:float(x[0]))))

print(result)
# Output
[   ('1', '1', '1', '1.1', '1.2', '1.2', '2', '2.2', '3', '3.2', '3.5'), 
    ('1', '1', '1', '1', '3', '2', '2', '2', '2', '3', '5'), 
    ('General', 'More', 'Another', 'Info', 'Titles', 'List', 'Info', 'Section', 'Here', 'Of', 'Strings')]

当我打印结果时,它返回<zip object at 0x000000000B6A54C8>。这是一个内存位置,对吗?为什么会返回这个呢? - Jstuff
@Jstuff,由于你使用Python3,请将zip(...)前面加上list。在Python3中,zip返回一个迭代器。请查看我的编辑答案。 - SparkAndShine
1
完美,这正是我在寻找的!不过有一个问题。在我处理的数据中,它有到第二位小数的十进制数,如1.10、1.11等,但排序时会变成1、1.1、1.10、1.11等。有没有办法告诉Python按照1.1、1.2、……、1.9、1.10等方式进行排序? - Jstuff
@Jstuff,好问题。将一个数字分割成整数和小数部分,使用zip打包它们,排序并合并它们。 - SparkAndShine
请耐心等待,我还不太熟悉Python。我尝试使用 l1_float = [float(i) for i in l1],但它会删除 1.10 的零,使其排序为 1、1.1、1.1、1.2,而不是想要的 1、1.1、1.2、1.10.0。有没有更好的方法可以保留尾随零?此外,为什么要将传入 lambda 函数的值转换为浮点数? - Jstuff
显示剩余2条评论

-1

我的方法是使用列表推导式,无需导入模块。我认为它很快,而且非常简单。

编辑:我添加了一种未排序的方法和一种排序的方法。

#Unsorted
newList =[
    [item for sublist in Section for item in sublist],
    [item for sublist in Page for item in sublist],
    [item for sublist in Titles for item in sublist]
    ]

print newList
#Output
#[[1, 1.1, 1.2, 1, 2, 2.2, 3, 1, 1.2, 3.2, 3.5], 
# [1, 1, 3, 1, 2, 2, 2, 1, 2, 3, 5], 
# ['General', 'Info', 'Titles', 'More', 'Info', 'Section', 'Here', 'Another', 'List', 'Of', 'Strings']]

#Sort first two lists afterwards, if desired
for i in range(2):
    newList[i].sort()

print newList
#Output
#[[1, 1, 1, 1.1, 1.2, 1.2, 2, 2.2, 3, 3.2, 3.5], 
# [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 5], 
# ['General', 'Info', 'Titles', 'More', 'Info', 'Section', 'Here', 'Another', 'List', 'Of', 'Strings']]

这不是 OP 所期望的结果,因为您独立地对列表进行了排序。 - SparkAndShine
@sparkandshine 哦,我理解他说他想要一个可以之后排序的表格。感谢反馈。我会编辑我的回答。 - Jeremy
也许我没有表达清楚,我只想对列表“Section”进行排序,其他两个列表应该按照“Section”列表排序后的顺序进行排序。例如,如果在对“Section”进行排序后,前几个索引更改为2、4、1,则其他两个列表需要将它们的索引更改为2、4、1。 - Jstuff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接