按 int 值将嵌套列表拆分为子列表
split nested list into sublists by int values
我有两个列表:
data = [[1,2,3,4], [5,6,7], [8,9,10,11,12,13,14]]
splitters = [3,7,10,13]
我想根据 splitter 中的值拆分 data 中的嵌套列表,条件如下:
- 不拆分,如果它是列表中的 first/last 值。
- 拆分器中的拆分值应位于新列表的末尾和。
- 应该是可迭代的,所以列表被分成与列表中的拆分器一样多的部分。
- 无冗余。
最终结果应该是这样的:
results = [[1,2,3],[3,4],[5,6,7],[8,9,10],[10,11,12,13],[13,14]
我的第一次尝试是这样的:
temp = []
for route in data:
for node in route:
if node in splitter and ((route.index(node) !=0) and (route.index(node) != (len(route)-1))):
#route should be splitted and save it for now with the splitter
temp.append([route, node])
#here a big part is missing
#start a new subroute
#maybe something like a whileloop with len(route)
#check the same if-statement for the remaining subroute
else:
#no splitter in this route, so keep the original route
temp.append([route, 0])
温度看起来像这样:
[[[1, 2, 3, 4], 0],
[[1, 2, 3, 4], 0],
[[1, 2, 3, 4], 3],
[[1, 2, 3, 4], 0],...]
基于此,我可以删除冗余路由并拆分路由,但我认为我的方法不必要地复杂,如果我想实现一些满足其他条件的东西会变得越来越混乱。
我的研究到目前为止还没有成功(使用 itertools.groupby 等)。这有点相关:https://www.reddit.com/r/learnpython/comments/3sk1xj/splitting_a_list_in_sublists_by_values/
希望知道一些 ideas/approaches 如何解决这个问题或将其细分为更小的部分。
为未来的读者编辑:
我更喜欢 maxiotic 的解决方案,因为它甚至可以处理这样的数据
data = [[1,2,3],[1,2,3,4,5,6,7]]
splitters = [1,2,3,4,7]
嵌套列表中的每个 start/end 都在拆分器中。 Relondom 解决方案中的问题是以下 if 语句,必须更改:
if inner[0] in splitters or inner[-1] in splitters: # check if first or last elemtn in splitters
非常感谢!
我不知道这是否是最佳方式,但我决定编写这段代码,因为还没有人回答。
res = []
for inner in data:
if inner[0] in splitters or inner[-1] in splitters: # check if first or last elemtn in splitters
res.append(inner)
continue
else:
temp = []
for val in inner:
if val not in splitters:
temp.append(val)
else:
temp.append(val) # list ends with value from splitters
res.append(temp) # add new list to result
temp = [val] # new list starts with value from splitters
if temp not in res:
res.append(temp)
这是我正在研究的解决方案:
results = []
for route in data:
found = 0
for idx, r in enumerate(route[1:-1], 1): # start idx at 1
if r in splitters:
temp = route[found:idx+1] # +1 to capture the splitter value
results.append(temp)
found = idx
remaining = route[found:]
results.append(remaining)
我有两个列表:
data = [[1,2,3,4], [5,6,7], [8,9,10,11,12,13,14]]
splitters = [3,7,10,13]
我想根据 splitter 中的值拆分 data 中的嵌套列表,条件如下:
- 不拆分,如果它是列表中的 first/last 值。
- 拆分器中的拆分值应位于新列表的末尾和。
- 应该是可迭代的,所以列表被分成与列表中的拆分器一样多的部分。
- 无冗余。
最终结果应该是这样的:
results = [[1,2,3],[3,4],[5,6,7],[8,9,10],[10,11,12,13],[13,14]
我的第一次尝试是这样的:
temp = []
for route in data:
for node in route:
if node in splitter and ((route.index(node) !=0) and (route.index(node) != (len(route)-1))):
#route should be splitted and save it for now with the splitter
temp.append([route, node])
#here a big part is missing
#start a new subroute
#maybe something like a whileloop with len(route)
#check the same if-statement for the remaining subroute
else:
#no splitter in this route, so keep the original route
temp.append([route, 0])
温度看起来像这样:
[[[1, 2, 3, 4], 0],
[[1, 2, 3, 4], 0],
[[1, 2, 3, 4], 3],
[[1, 2, 3, 4], 0],...]
基于此,我可以删除冗余路由并拆分路由,但我认为我的方法不必要地复杂,如果我想实现一些满足其他条件的东西会变得越来越混乱。
我的研究到目前为止还没有成功(使用 itertools.groupby 等)。这有点相关:https://www.reddit.com/r/learnpython/comments/3sk1xj/splitting_a_list_in_sublists_by_values/
希望知道一些 ideas/approaches 如何解决这个问题或将其细分为更小的部分。
为未来的读者编辑: 我更喜欢 maxiotic 的解决方案,因为它甚至可以处理这样的数据
data = [[1,2,3],[1,2,3,4,5,6,7]]
splitters = [1,2,3,4,7]
嵌套列表中的每个 start/end 都在拆分器中。 Relondom 解决方案中的问题是以下 if 语句,必须更改:
if inner[0] in splitters or inner[-1] in splitters: # check if first or last elemtn in splitters
非常感谢!
我不知道这是否是最佳方式,但我决定编写这段代码,因为还没有人回答。
res = []
for inner in data:
if inner[0] in splitters or inner[-1] in splitters: # check if first or last elemtn in splitters
res.append(inner)
continue
else:
temp = []
for val in inner:
if val not in splitters:
temp.append(val)
else:
temp.append(val) # list ends with value from splitters
res.append(temp) # add new list to result
temp = [val] # new list starts with value from splitters
if temp not in res:
res.append(temp)
这是我正在研究的解决方案:
results = []
for route in data:
found = 0
for idx, r in enumerate(route[1:-1], 1): # start idx at 1
if r in splitters:
temp = route[found:idx+1] # +1 to capture the splitter value
results.append(temp)
found = idx
remaining = route[found:]
results.append(remaining)