【问题标题】:Arranging nested tuples排列嵌套元组
【发布时间】:2013-12-02 03:30:42
【问题描述】:

我知道这可能是一个愚蠢的问题,对此我深表歉意,但我对 python 很陌生,并且已经尝试解决这个问题很长时间,但没有成功。 我有一个类似于下面的元组列表:

data = [('ralph picked', ['nose', '4', 'apple', '30', 'winner', '3']), 
('aaron popped', ['soda', '1', 'popcorn', '6', 'pill', '4', 'question', '29'])]

我想对嵌套列表进行降序排序:

data = [('ralph picked', ['apple', '30', 'nose', '4', 'winner', '3']), 
('aaron popped', ['question', '29', 'popcorn', '6', 'pill', '4', 'soda', '1'])]

我尝试使用简单

sorted(data)

但我得到的只是已排序的元组的第一项。我在这里缺少什么?我真的很感谢你的帮助。

【问题讨论】:

  • 我不会称之为排序。你正在做的是安排
  • 为什么4在第一个例子的第一行出现一次,而在第二个例子的第一行出现两次?再多的排序也不会将六元素列表变成七元素列表。
  • @Kevin,谢谢 kevin,这是一个错字,我已修正。
  • @AshishNitinPatil 感谢您的澄清,正如我所说,python 新手,这种评论有帮助。
  • 这正是我制作它的原因,以提供帮助! :)

标签: list sorting python-3.x tuples


【解决方案1】:

让我们只考虑内部列表。第一个问题是您似乎想将单词、数字对保持在一起。我们可以使用zip 来组合它们,记住seq[::2] 给我们从第0 个开始的第二个元素,而seq[1::2] 给我们从第一个开始的每一秒:

>>> s = ['nose', '4', 'apple', '30', 'winner', '3']
>>> zip(s[::2], s[1::2])
<zip object at 0xb5e996ac>
>>> list(zip(s[::2], s[1::2]))
[('nose', '4'), ('apple', '30'), ('winner', '3')]

现在,正如您所发现的,如果您在一个序列上调用 sorted,它首先按第一个元素排序,然后按第二个元素进行排序,以此类推,尽可能深入。因此,如果我们就此致电sorted

>>> sorted(zip(s[::2], s[1::2]))
[('apple', '30'), ('nose', '4'), ('winner', '3')]

嗯,这看起来可行,但只是侥幸,因为apple-nose-winner 是按字母顺序排列的。真的,我们想按第二项排序。 sorted 接受 key 参数:

>>> sorted(zip(s[::2], s[1::2]), key=lambda x: x[1])
[('winner', '3'), ('apple', '30'), ('nose', '4')]

这也不起作用,因为它按字典顺序对数字字符串进行排序(字典样式,因此 '30' 位于 '4' 之前)。不过,我们可以告诉它我们想要使用数值:

>>> sorted(zip(s[::2], s[1::2]), key=lambda x: int(x[1]))
[('winner', '3'), ('nose', '4'), ('apple', '30')]

快到了——我们想要反转:

>>> sorted(zip(s[::2], s[1::2]), key=lambda x: int(x[1]), reverse=True)
[('apple', '30'), ('nose', '4'), ('winner', '3')]

这几乎是正确的,但我们需要将其展平。我们可以使用嵌套列表推导:

>>> s2 = sorted(zip(s[::2], s[1::2]), key=lambda x: int(x[1]), reverse=True)
>>> [value for pair in s2 for value in pair]
['apple', '30', 'nose', '4', 'winner', '3']

或使用itertools.chain:

>>> from itertools import chain
>>> list(chain.from_iterable(s2))
['apple', '30', 'nose', '4', 'winner', '3']

我认为这就是我们想要去的地方。

【讨论】:

  • 哇,这非常清晰和具有指导意义,谢谢。不过,我很抱歉,因为我不知道如何使您的答案适应我现有的列表。我可能遗漏了一些东西,但我真的需要将内部列表保留在更大的列表中。关于如何使用嵌套部分使其适用于我现有列表的任何提示?
  • 这很简单。你知道如何遍历列表并通过索引修改元素吗?
  • 我能够创建循环,但现在我在sorted(zip(s[::2], s[1::2]), key=lambda x: int(x[1]), reverse=True) 行收到一条错误消息,上面写着int() argument must be a string or a number, not 'tuple'。我尝试替换 int 但没有成功。关于这怎么可能的任何想法?我真的很感激。
猜你喜欢
  • 1970-01-01
  • 2013-12-12
  • 2011-04-19
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多