如何根据python中的公共元素改变列表的顺序?



我有以下列表:

l1 = ['foo_x', 'bar_x', 'xyz_x', 'foo_y', 'bar_y', 'xyz_y']

我创建了一个包含公共元素的列表。

l2 = ['foo', 'bar', 'xyz']
# trying to reorder which is not successful
[i for i in l1 if (l2 in l1)]

我想改变l1的顺序,得到以下结果:

['foo_x', 'foo_y', 'bar_x', 'bar_y', 'xyz_x', 'xyz_y']

假设l1中的每个元素都是l2某个元素的超字符串,则可以使用next根据第一个匹配元素的索引进行排序。

>>> l1 = ['foo_x', 'bar_x', 'xyz_x', 'foo_y', 'bar_y', 'xyz_y']    
>>> l2 = ['foo', 'bar', 'xyz']
>>> sorted(l1, key=lambda x: next(i for i, e in enumerate(l2) if e in x))
['foo_x', 'foo_y', 'bar_x', 'bar_y', 'xyz_x', 'xyz_y']

next表示l1中每个元素的线性复杂度(以l2的大小表示)。如果_是有效的,也就是说,如果l2中的元素总是在_之前,你可以创建一个字典,将每个元素映射到它的索引,然后直接使用该子字符串查找该索引。

>>> l2_idx = {e: i for i, e in enumerate(l2)}
>>> sorted(l1, key=lambda x: l2_idx[x[:x.index("_")]])
['foo_x', 'foo_y', 'bar_x', 'bar_y', 'xyz_x', 'xyz_y']

在这种形式下,如果l2中没有匹配的元素,这两种方法都将失败,但是在这种情况下,您可以同时提供一个默认元素来使用,例如len(l2)

IIUC,您需要.split(),然后在l2_后的最后一部分排序基本索引,如下所示:

>>> l1 = ['foo_x', 'bar_x', 'xyz_x', 'foo_y', 'bar_y', 'xyz_y']
>>> l2 = ['foo', 'bar', 'xyz']
>>> sorted(l1, key=lambda x: (l2.index(x.split('_')[0]), x.split('_')[1]))
['foo_x', 'foo_y', 'bar_x', 'bar_y', 'xyz_x', 'xyz_y']

另一个例子:

>>> l1 = ['foo_x', 'bar_x', 'xyz_x', 'foo_y', 'bar_y', 'xyz_y' , 'foo_a', 'bar_b', 'xyz_c']
>>> l2 = [ 'xyz' , 'foo', 'bar']
>>> sorted(l1, key=lambda x: (l2.index(x.split('_')[0]), x.split('_')[1]))
['xyz_c',
'xyz_x',
'xyz_y',
'foo_a',
'foo_x',
'foo_y',
'bar_b',
'bar_x',
'bar_y']

相关内容

  • 没有找到相关文章

最新更新