我有以下列表:
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']