基于具有元组和非元组的索引列表的python方法来拉出和分组列表项



考虑一个列表。在我的实际问题中,这些东西是matplotlib艺术家,但对于更普遍的情况,我们称列表为list_of_things:

list_of_things = ["one", "two", "three", "four", "five"]

另外,我们有一个list_of_things的索引列表,其中的列表元素可以分组也可以不分组到元组中。我们称其为list_of_indices:

list_of_indices = [(3, 1), (2, 0), 4]

期望的结果是一个包含list_of_things项目的新列表,该列表保留list_of_indices项目的顺序和形状,如下所示:

desired_result = [("four", "two"), ("three", "one"), "five"]
解决这个问题的一种方法是通过循环,使用空列表作为结果的收集器:
results = []
for item in list_of_indices:
if isinstance(item, tuple):
results.append(
(list_of_things[item[0]], 
list_of_things[item[1]])
)
else:
results.append(list_of_things[item])
print(results)
>>> [('four', 'two'), ('three', 'one'), 'five']

但是这个感觉很迟钝。似乎应该有一种更python化、更优化的方式来做同样的事情。

对于好奇的人来说,我所追求的是将matplotlib艺术家处理(即在pyplot.axes中绘制的东西)组合在一起的能力,以便我可以使用matplotlib.legend_handler.HandlerTuple方法组合图例项目。这对于绘制回归和相关置信区间,并且只想显示一个图例条目的情况非常有用。元组句柄绘制在一起。

operator.itemgetter将是一个很好的选择(通过任意索引获取值):

from operator import itemgetter
res = [itemgetter(*(el if isinstance(el, tuple) else [el]))(list_of_things)
for el in list_of_indices]

[('four', 'two'), ('three', 'one'), 'five']

我们可以为索引列表中找到的每种类型创建map方法。因为我们只有两种类型,这些就足够了:

def map_int(lst, i):
return lst[i]
def map_tuple(lst, tpl):
return tuple(lst[t] for t in tpl)
然后,我们应该有一个工厂方法来调用正确的映射器:(注意我使用了模式匹配,你也可以使用简单的if)
def map_all(lst, tpl_or_int):
match tpl_or_int:
case int(i):
return map_int(lst, i)
case tuple(tpl):
return map_tuple(lst, tpl)

最后,我们可以使用工厂方法映射所有的索引。

list_of_things = ["one", "two", "three", "four", "five"]
list_of_indices = [(3, 1), (2, 0), 4]
result = list(map(lambda i: map_all(list_of_things, i), list_of_indices))

您可以使用numpy来做到这一点:

>>> [np.array(list_of_things)[(i,)].tolist() for i in list_of_indices]
[['four', 'two'], ['three', 'one'], 'five']

显然,如果list_of_things已经是numpy数组,则不需要强制转换为array:

list_of_things = np.array(list_of_things)
out = [list_of_things[(i,)].tolist() for i in list_of_indices]

相关内容

  • 没有找到相关文章