将列表列表的结构复制到平面列表?
Copying structure of a list of list to a flat list?
我有两个列表如下。
l1=[a,b,c,d,e]
l2=[[p,q],[r,s,t]]
如何从 l1 创建类似于列表 l2 的列表列表?
期望的输出:
[[a,b],[c,d,e]]
非常感谢您的帮助。谢谢!
您可以创建一个空列表来存储结果,并创建一个count
变量来存储每个子列表的起始索引,然后对于l2
中的每个子列表,获取大小子列表,并从列表 l1
中取出项目
res = []
count = 0
for sub in l2:
res.append(l1[count:len(sub)+count])
count += len(sub)
输出:
res
Out[79]: [['a', 'b'], ['c', 'd', 'e']]
一种可能的方法:使用deepcopy(l2)
创建新列表的结构,然后递归遍历它并将其非列表项替换为从l1
的副本中获取的项。
>>> a, b, c, d, e = "abcde"
>>> p, q, r, s, t = "pqrst"
>>> l1=[a,b,c,d,e]
>>> l2=[[p,q],[r,s,t]]
>>> from copy import deepcopy
>>> l3 = deepcopy(l2)
>>> def deep_replace(l1, l2):
... for i, item in enumerate(l2):
... if isinstance(item, list):
... deep_replace(l1, item)
... else:
... l2[i] = l1.pop(0)
...
>>> deep_replace(l1.copy(), l3)
>>> l3
[['a', 'b'], ['c', 'd', 'e']]
这应该适用于任意深度的列表(无论如何达到 Python 的递归限制)。
如果保留原始 l1
和 l2
并不重要,您可以跳过 copy
和 deepcopy
调用。
以下方法适用于任意嵌套的列表,不需要深度复制,也不需要低效的 pop
从列表末尾开始,使这个版本与项目总数成线性关系,而不是二次方的:
def structured_replace(values, nested):
it = iter(values)
def _helper(nested):
return [
_helper(item) if isinstance(item, list) else next(it)
for item in nested
]
return _helper(nested)
a, b, c, d, e = "abcde"
p, q, r, s, t = "pqrst"
l1 = [a,b,c,d,e]
l2 = [[p,q],[r,s,t]]
print(structured_replace(l1, l2))
此外,为了好玩,这里有一个迭代解决方案:
def structured_replace(values, nested):
it = iter(values)
top_result = []
stack = [(nested, top_result)]
while stack:
item, result = stack.pop()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in reversed(item):
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
此外,这里有一个广度优先方法,我们可以轻松修改迭代方法并使用标准的基于队列的方法:
def structured_replace_breadth_first(values, nested):
from collections import deque
it = iter(values)
top_result = []
stack = deque([(nested, top_result)])
while stack:
item, result = stack.popleft()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in item:
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
差异:
In [5]: structured_replace('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[5]: [['a', 'b'], 'c', ['d', ['e', 'f'], 'g']]
In [6]: structured_replace_level_first('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[6]: [['b', 'c'], 'a', ['d', ['f', 'g'], 'e']]
我有两个列表如下。
l1=[a,b,c,d,e]
l2=[[p,q],[r,s,t]]
如何从 l1 创建类似于列表 l2 的列表列表?
期望的输出: [[a,b],[c,d,e]]
非常感谢您的帮助。谢谢!
您可以创建一个空列表来存储结果,并创建一个count
变量来存储每个子列表的起始索引,然后对于l2
中的每个子列表,获取大小子列表,并从列表 l1
res = []
count = 0
for sub in l2:
res.append(l1[count:len(sub)+count])
count += len(sub)
输出:
res
Out[79]: [['a', 'b'], ['c', 'd', 'e']]
一种可能的方法:使用deepcopy(l2)
创建新列表的结构,然后递归遍历它并将其非列表项替换为从l1
的副本中获取的项。
>>> a, b, c, d, e = "abcde"
>>> p, q, r, s, t = "pqrst"
>>> l1=[a,b,c,d,e]
>>> l2=[[p,q],[r,s,t]]
>>> from copy import deepcopy
>>> l3 = deepcopy(l2)
>>> def deep_replace(l1, l2):
... for i, item in enumerate(l2):
... if isinstance(item, list):
... deep_replace(l1, item)
... else:
... l2[i] = l1.pop(0)
...
>>> deep_replace(l1.copy(), l3)
>>> l3
[['a', 'b'], ['c', 'd', 'e']]
这应该适用于任意深度的列表(无论如何达到 Python 的递归限制)。
如果保留原始 l1
和 l2
并不重要,您可以跳过 copy
和 deepcopy
调用。
以下方法适用于任意嵌套的列表,不需要深度复制,也不需要低效的 pop
从列表末尾开始,使这个版本与项目总数成线性关系,而不是二次方的:
def structured_replace(values, nested):
it = iter(values)
def _helper(nested):
return [
_helper(item) if isinstance(item, list) else next(it)
for item in nested
]
return _helper(nested)
a, b, c, d, e = "abcde"
p, q, r, s, t = "pqrst"
l1 = [a,b,c,d,e]
l2 = [[p,q],[r,s,t]]
print(structured_replace(l1, l2))
此外,为了好玩,这里有一个迭代解决方案:
def structured_replace(values, nested):
it = iter(values)
top_result = []
stack = [(nested, top_result)]
while stack:
item, result = stack.pop()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in reversed(item):
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
此外,这里有一个广度优先方法,我们可以轻松修改迭代方法并使用标准的基于队列的方法:
def structured_replace_breadth_first(values, nested):
from collections import deque
it = iter(values)
top_result = []
stack = deque([(nested, top_result)])
while stack:
item, result = stack.popleft()
if isinstance(item, list):
subresult = []
result.append(subresult)
for sub in item:
stack.append((sub, subresult))
else:
result.append(next(it))
return top_result[0]
差异:
In [5]: structured_replace('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[5]: [['a', 'b'], 'c', ['d', ['e', 'f'], 'g']]
In [6]: structured_replace_level_first('abcdefg', [[1, 2], 3, [4, [5, 6], 7]])
Out[6]: [['b', 'c'], 'a', ['d', ['f', 'g'], 'e']]