遍历嵌套列表并选择某些元素并创建一个新列表
Iterate through a nested list and pick certain elements and create a new list
一个例子:
list = [[2, 1, 2, 3, 4],
[0, 4, 5],
[1, 8, 9]]
所以嵌套列表中的第一个索引决定了后面哪些数字将被放入非嵌套列表中。
[2, 1, 2, 3, 4] -> 2: so 1 and 2 gets picked up
[0, 4, 5] -> 0: no number gets picked up
[1, 8, 9] -> 1; number 8 gets picked up
输出将是:
[1, 2, 8]
这是我目前拥有的:
def nested_list(numbers):
if isinstance(numbers[0], list):
if numbers[0][0] > 0:
nested_list(numbers[0][1:numbers[0][0] + 1])
else:
numbers = list(numbers[0])
return numbers + nested_list(numbers[1:])
我试图通过递归获取列表,但出了点问题。我错过了什么或者即使没有递归也能完成吗?
你可以试试列表理解:
>>> [sub[i] for sub in lst for i in range(1, sub[0]+1) ]
[1, 2, 8]
PS: 该解决方案期望每个子列表都是一个非空列表,否则它将抛出 IndexError
异常,因为 sub[0]
.
您尝试在此处使用列表理解和元组解包。
[val for idx, *rem in lst for val in rem[:idx]]
# [1, 2, 8]
NB This solution assumes you would always have a sub-list of size 1 or greater. We can filter out empty sub-lists using filter(None, lst)
list1=[[2, 1, 2, 3, 4],
[0, 4, 5],
[1, 8, 9]]
list2= []
for nested_list in list1:
for i in range(nested_list[0]):
list2.append(nested_list[i+1])
另一个列表理解
sum([x[1:x[0] + 1] for x in arr], [])
# [1, 2, 8]
使用builtin function map
to apply the picking function, and using itertools.chain
展平列表的结果列表:
def pick(l):
return l[1:1+l[0]]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9]]
print( list(map(pick, ll)) )
# [[1, 2], [], [8]]
print( list(itertools.chain.from_iterable((map(pick, ll)))) )
# [1, 2, 8]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9]]
print( [x for l in ll for x in l[1:1+l[0]]] )
# [1, 2, 8]
两个重要说明:
我已将您的列表重命名为 ll
而不是 list
。这是因为 list
已经是 python 中内置 class list
的名称。隐藏内置函数的名称是非常危险的,并且会产生意想不到的后果。我强烈建议您在命名自己的变量时永远不要使用内置名称。
对于上述两种解决方案,错误处理的行为相同:如果其中一个子列表为空,将引发异常 IndexError
(因为我们需要访问第一个元素才能知道选择多少个元素,因此如果没有第一个元素,则会引发错误)。但是,如果其中一个子列表中的元素不足,则不会引发异常。例如,如果其中一个子列表是 [12, 3, 4]
,那么上面的两个解决方案都会默默地选择两个元素 3 和 4,即使他们被要求选择 12 个元素而不仅仅是 2 个。如果你想要一个例外针对这种情况提出,可以修改第一种方案中的函数pick
:
def pick(l):
if len(l) == 0 or len(l) <= l[0]:
raise ValueError('in function pick: two few elements in sublist {}'.format(l))
return l[1:1+l[0]]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9], [12, 3, 4]]
print( [x for l in ll for x in l[1:1+l[0]]] )
# [1, 2, 8, 3, 4]
print( [x for l in ll for x in pick(l)] )
# ValueError: in function pick: two few elements in sublist [12, 3, 4]
一个例子:
list = [[2, 1, 2, 3, 4],
[0, 4, 5],
[1, 8, 9]]
所以嵌套列表中的第一个索引决定了后面哪些数字将被放入非嵌套列表中。
[2, 1, 2, 3, 4] -> 2: so 1 and 2 gets picked up
[0, 4, 5] -> 0: no number gets picked up
[1, 8, 9] -> 1; number 8 gets picked up
输出将是:
[1, 2, 8]
这是我目前拥有的:
def nested_list(numbers):
if isinstance(numbers[0], list):
if numbers[0][0] > 0:
nested_list(numbers[0][1:numbers[0][0] + 1])
else:
numbers = list(numbers[0])
return numbers + nested_list(numbers[1:])
我试图通过递归获取列表,但出了点问题。我错过了什么或者即使没有递归也能完成吗?
你可以试试列表理解:
>>> [sub[i] for sub in lst for i in range(1, sub[0]+1) ]
[1, 2, 8]
PS: 该解决方案期望每个子列表都是一个非空列表,否则它将抛出 IndexError
异常,因为 sub[0]
.
您尝试在此处使用列表理解和元组解包。
[val for idx, *rem in lst for val in rem[:idx]]
# [1, 2, 8]
NB This solution assumes you would always have a sub-list of size 1 or greater. We can filter out empty sub-lists using
filter(None, lst)
list1=[[2, 1, 2, 3, 4],
[0, 4, 5],
[1, 8, 9]]
list2= []
for nested_list in list1:
for i in range(nested_list[0]):
list2.append(nested_list[i+1])
另一个列表理解
sum([x[1:x[0] + 1] for x in arr], [])
# [1, 2, 8]
使用builtin function map
to apply the picking function, and using itertools.chain
展平列表的结果列表:
def pick(l):
return l[1:1+l[0]]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9]]
print( list(map(pick, ll)) )
# [[1, 2], [], [8]]
print( list(itertools.chain.from_iterable((map(pick, ll)))) )
# [1, 2, 8]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9]]
print( [x for l in ll for x in l[1:1+l[0]]] )
# [1, 2, 8]
两个重要说明:
我已将您的列表重命名为
ll
而不是list
。这是因为list
已经是 python 中内置 classlist
的名称。隐藏内置函数的名称是非常危险的,并且会产生意想不到的后果。我强烈建议您在命名自己的变量时永远不要使用内置名称。对于上述两种解决方案,错误处理的行为相同:如果其中一个子列表为空,将引发异常
IndexError
(因为我们需要访问第一个元素才能知道选择多少个元素,因此如果没有第一个元素,则会引发错误)。但是,如果其中一个子列表中的元素不足,则不会引发异常。例如,如果其中一个子列表是[12, 3, 4]
,那么上面的两个解决方案都会默默地选择两个元素 3 和 4,即使他们被要求选择 12 个元素而不仅仅是 2 个。如果你想要一个例外针对这种情况提出,可以修改第一种方案中的函数pick
:
def pick(l):
if len(l) == 0 or len(l) <= l[0]:
raise ValueError('in function pick: two few elements in sublist {}'.format(l))
return l[1:1+l[0]]
ll = [[2, 1, 2, 3, 4], [0, 4, 5], [1, 8, 9], [12, 3, 4]]
print( [x for l in ll for x in l[1:1+l[0]]] )
# [1, 2, 8, 3, 4]
print( [x for l in ll for x in pick(l)] )
# ValueError: in function pick: two few elements in sublist [12, 3, 4]