【问题标题】:Slice array of tuples by its elements按元素对元组数组进行切片
【发布时间】:2021-06-10 14:30:15
【问题描述】:

例如,我有一个元组数组。

l=[(456,33,1),
   (556,22,1),
   (123,33,2),
   (557,32,2),
   (435,21,2)]

我想通过每个元组中的最后一个元素来制作列表数组,这样

l=[[(456,33),
   (556,22)],
  [(123,33),
   (557,32),
   (435,21)]]

我怎么能这样做?有什么优雅的方式吗?

【问题讨论】:

  • 假设列表已经根据元组的第三个条目排序是否安全?

标签: python arrays list tuples


【解决方案1】:
l = [(456, 33, 1), (556, 22, 1), (123, 33, 2), (557, 32, 2), (435, 21, 2)]

out = {}
for v in l:
    out.setdefault(v[-1], []).append(v[:-1])

out = list(out.values())
print(out)

打印:

[[(456, 33), (556, 22)], 
 [(123, 33), (557, 32), (435, 21)]]

【讨论】:

  • 根据 OP 使用的 python 实现及其需求,他们可能会遇到out 中元素出现顺序的问题(可能与l 不同步) .否则我觉得这个解决方案超级优雅。 +1
【解决方案2】:

另一种方法是使用itertools.groupby

from itertools import groupby
from operator import itemgetter

res = [[x[:-1] for x in g] for _, g in groupby(sorted(l, key=itemgetter(2)), itemgetter(2))]

产生所需的:

[[(456, 33), (556, 22)], [(123, 33), (557, 32), (435, 21)]]

请注意,如果您可以保证原始列表 l 按元组中的第 3 项排序,则可以将 sorted(l, key=itemgetter(2)) 替换为仅 l

【讨论】:

  • 还请注意,如果您只想遍历结果序列,则无需创建完整的列表列表。在这种情况下,这将简化为for key, group in groupby(l, key=itemgetter(2)),其中key 将是原始元组的第三个条目,group 将是所有元组的迭代器,key 作为第三个条目。
  • @Brian 当然。但是,我将把它留给 OP 来决定。
【解决方案3】:

另一种尝试是使用这个:

l=[(456,33,1),
   (556,22,1),
   (123,33,2),
   (557,32,2),
   (435,21,2)]
   
dict_ = {}
for v in l:
  val1, val2, id_ = v
  dict_[id_] = [[val1, val2]] if id_ not in dict_ else dict_[id_] + [[val1, val2]]
    
l = [dict_[x] for x in dict_]

【讨论】:

    猜你喜欢
    • 2016-04-16
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2017-10-04
    相关资源
    最近更新 更多