根据条件拆分列表,将函数应用于子列表,并在Python中按原始顺序组合



我有一个包含不同类型元素的列表。我需要根据它们在子列表中的种类来划分列表(这里以"a"或"b"开头,所以有2个子列表(。

l = ['a1', 'b1', 'a2', 'a3', 'b2', 'b3']

然后分别处理这些子列表。处理的结果(例如,对服务器的远程调用(再次是具有相同长度的两个列表。我只想打2个电话,而不是n=len(l)个电话,因为这要便宜得多。

接下来,我必须按照原来的顺序把这些清单重新放在一起。

# original list
l = ['a1', 'b1', 'a2', 'a3', 'b2', 'b3']
# sublists which need to be processed separately
sl1 = [item for item in l if item.startswith('a')]
sl2 = [item for item in l if not item.startswith('a')]
# expensive call to server
f1 = lambda l: [x + '_calc1' for x in l ]
f2 = lambda l: [x + '_calc2' for x in l ]
sr1 = f1(sl1)
sr2 = f2(sl2)
# rebuild list according to original order
a = iter(sr1)
b = iter(sr2)
l_result = [next(a) if x.startswith('a') else next(b) for x in l]
# >> ['a1_calc1', 'b1_calc2', 'a2_calc1', 'a3_calc1', 'b2_calc2', 'b3_calc2']

我目前做这件事的方式感觉很笨拙,我希望有一种"蟒蛇式"的方式来做这些拆分-应用-组合。

Alternate,可能不那么笨拙(PS。我已经写下了一个骨架,你可以通过添加函数或使用适当方法的类来提高它的可读性

l = original_list
type_1 = [(i, x) for i,x in enumerate(l) if condition_type_1(x)]
type_2 = [(i, x) for i,x in enumerate(l) if condition_type_2(x)]
response_1 = server_request_1([x[1] for x in type_1])
response_2 = server_request_2([x[1] for x in type_2])
response_1 = [(tp[0], resp) for tp, resp in zip(type_1, response_1)]
response_2 = [(tp[0], resp) for tp, resp in zip(type_2, response_2)]
response = response_1 + response_2
response = sorted(response, key=lambda k:k[0])
response = [x[1] for x in response]

如果可以保留l中位置的原始索引,则可以将结果重新放入新列表:

l = ['a1', 'b1', 'a2', 'a3', 'b2', 'b3']
e = [(idx,item) for (idx,item) in enumerate(l)]
sl1 = [item for item in e if item[1].startswith('a')]
sl2 = [item for item in e if not item[1].startswith('a')]
# expensive call to server
f1 = lambda l: [x[1] + '_calc1' for x in l ]
f2 = lambda l: [x[1] + '_calc2' for x in l ]
sr1 = f1(sl1)
sr2 = f2(sl2)
l_result = [None] * len(l)
for idx,item in enumerate(sr1):
idx,_ = sl1[idx]
l_result[idx] = item

for idx,item in enumerate(sr2):
idx,_ = sl2[idx]
l_result[idx] = item
print(l_result)

最新更新