如何迭代 python 中的多维任意列表
How to iterate over an multidimensional arbitrary list in python
我有一个表达式 Tree,它生成树列表。列表因用于计算数字的表达式而异,例如,
T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
或
T = ['+', ['*', 5, 4] ,['-', 100, ['/', 20, 2] ]]
我想遍历树的每一个元素,并将运算符的索引、所有运算符的列表、数字的索引和数字列表存储在一个数组中。为此,我试图找出一种可以循环到列表中的方法,然后只检查类型是否为字符串,这意味着它是一个运算符,并通过附加将该索引和值存储在相应的数组中,否则如果类型是数字,然后将其与所有数字一起存储在数组中。
我尝试了下面的代码
T = T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
for i in range(0,len(T)):
if type(T[i]) != int:
for j in range(0,len(T[i])):
print(T[i][j])
else:
print(T[i])
运行 代码给出输出:
-
+
['-', 75, ['-', 10, 3]]
['-', 100, 50]
3
我们基本上想要实现的是进入列表,直到我们可以根据列表大小。关于这如何可能的任何想法?
我的回答基本上是:
address list of the operators is [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]]
list of the operators is ['-', '+', '-', '-', '-']
address of the numbers is [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]]
list of the numbers is [75, 10, 3, 100, 50, 3]
您可以使用递归函数。可以改进以下内容,例如同时处理运算符和数字。
T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
def evaluate(arg): # not requested, but why not?
if type(arg) is list:
return eval(f'{evaluate(arg[1])} {arg[0]} {evaluate(arg[2])}')
else:
return arg
def get_ops(arg): # returns (list of operators, list of their indices)
ops = [arg[0]] # first elem is an operator, so add it
idx = [[0]] # add this index 0
for i in (1, 2): # for each position 1 and 2,
if type(arg[i]) is list: # if NOT scalar
ops_sub, idx_sub = get_ops(arg[i]) # recurse!
ops += ops_sub # add the list of ops from the sublist
idx += [[i] + x for x in idx_sub] # add idx list from the sublist,
# while the position of the sublist
# being PREPENDED to each idx
return ops, idx
def get_nums(arg): # basically the same goes here
nums = []
idx = []
for i in (1, 2):
if type(arg[i]) is list:
nums_sub, idx_sub = get_nums(arg[i])
nums += nums_sub
idx += [[i] + x for x in idx_sub]
else: # if scalar, this IS a number, so add it to the output
nums.append(arg[i])
idx.append([i])
return nums, idx
print(get_ops(T))
print(get_nums(T))
print(evaluate(T))
结果:
(['-', '+', '-', '-', '-'], [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]])
([75, 10, 3, 100, 50, 3], [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]])
115
您可以将单个递归生成器函数与 collections.defaultdict
一起使用:
from collections import defaultdict
def get_ops(t, p = []):
if isinstance(t, int):
yield ('val', t, p)
else:
yield ('op', t[0], p+[0])
yield from get_ops(t[1], p+[1])
yield from get_ops(t[2], p+[2])
T, d = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3], defaultdict(list)
for a, b, c in get_ops(T):
d[f'{a}_index'].append(c)
d[f'{a}s'].append(b)
print(dict(d))
输出:
{
'op_index': [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]],
'ops': ['-', '+', '-', '-', '-'],
'val_index': [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]],
'vals': [75, 10, 3, 100, 50, 3]
}
我有一个表达式 Tree,它生成树列表。列表因用于计算数字的表达式而异,例如,
T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
或
T = ['+', ['*', 5, 4] ,['-', 100, ['/', 20, 2] ]]
我想遍历树的每一个元素,并将运算符的索引、所有运算符的列表、数字的索引和数字列表存储在一个数组中。为此,我试图找出一种可以循环到列表中的方法,然后只检查类型是否为字符串,这意味着它是一个运算符,并通过附加将该索引和值存储在相应的数组中,否则如果类型是数字,然后将其与所有数字一起存储在数组中。
我尝试了下面的代码
T = T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
for i in range(0,len(T)):
if type(T[i]) != int:
for j in range(0,len(T[i])):
print(T[i][j])
else:
print(T[i])
运行 代码给出输出:
-
+
['-', 75, ['-', 10, 3]]
['-', 100, 50]
3
我们基本上想要实现的是进入列表,直到我们可以根据列表大小。关于这如何可能的任何想法?
我的回答基本上是:
address list of the operators is [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]]
list of the operators is ['-', '+', '-', '-', '-']
address of the numbers is [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]]
list of the numbers is [75, 10, 3, 100, 50, 3]
您可以使用递归函数。可以改进以下内容,例如同时处理运算符和数字。
T = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3]
def evaluate(arg): # not requested, but why not?
if type(arg) is list:
return eval(f'{evaluate(arg[1])} {arg[0]} {evaluate(arg[2])}')
else:
return arg
def get_ops(arg): # returns (list of operators, list of their indices)
ops = [arg[0]] # first elem is an operator, so add it
idx = [[0]] # add this index 0
for i in (1, 2): # for each position 1 and 2,
if type(arg[i]) is list: # if NOT scalar
ops_sub, idx_sub = get_ops(arg[i]) # recurse!
ops += ops_sub # add the list of ops from the sublist
idx += [[i] + x for x in idx_sub] # add idx list from the sublist,
# while the position of the sublist
# being PREPENDED to each idx
return ops, idx
def get_nums(arg): # basically the same goes here
nums = []
idx = []
for i in (1, 2):
if type(arg[i]) is list:
nums_sub, idx_sub = get_nums(arg[i])
nums += nums_sub
idx += [[i] + x for x in idx_sub]
else: # if scalar, this IS a number, so add it to the output
nums.append(arg[i])
idx.append([i])
return nums, idx
print(get_ops(T))
print(get_nums(T))
print(evaluate(T))
结果:
(['-', '+', '-', '-', '-'], [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]])
([75, 10, 3, 100, 50, 3], [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]])
115
您可以将单个递归生成器函数与 collections.defaultdict
一起使用:
from collections import defaultdict
def get_ops(t, p = []):
if isinstance(t, int):
yield ('val', t, p)
else:
yield ('op', t[0], p+[0])
yield from get_ops(t[1], p+[1])
yield from get_ops(t[2], p+[2])
T, d = ['-', ['+', ['-', 75, ['-', 10, 3]], ['-', 100, 50]], 3], defaultdict(list)
for a, b, c in get_ops(T):
d[f'{a}_index'].append(c)
d[f'{a}s'].append(b)
print(dict(d))
输出:
{
'op_index': [[0], [1, 0], [1, 1, 0], [1, 1, 2, 0], [1, 2, 0]],
'ops': ['-', '+', '-', '-', '-'],
'val_index': [[1, 1, 1], [1, 1, 2, 1], [1, 1, 2, 2], [1, 2, 1], [1, 2, 2], [2]],
'vals': [75, 10, 3, 100, 50, 3]
}