如何在Python中迭代多维任意列表

3
我有一个表达式树,生成了一个树形列表。列表的内容取决于用于计算数字的表达式,例如:

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] 

了解一下递归 - Scott Hunter
1
@Mark 刚刚编辑了这个问题,期望的输出在帖子的末尾,基本上是所有数字和运算符索引列表以及它们的值。 - Nihar
@ScottHunter 如果我正在进行递归,如何获取有关索引的信息?例如,有时索引是[0],但有时必须是[1, 1, 0]或[1, 1, 2, 0](从期望的输出中)。 - Nihar
2个回答

1
你可以使用递归函数。例如,通过同时处理运算符和数字,可以改进以下内容。
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

感谢您的评论,我已经试过了3-4棵不同的树,代码是有效的。 :) - Nihar
1
@Nihar 很高兴能帮到你!这是一次有趣的练习。 - j1-lee

1
您可以使用一个带有 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]
}

1
@Nihar 很高兴能帮忙! - Ajax1234

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接