Python 转换为dict/type列表,一个包含字符串列表的字符串列表?

Python 转换为dict/type列表,一个包含字符串列表的字符串列表?,python,functional-programming,apply,mutation,list-manipulation,Python,Functional Programming,Apply,Mutation,List Manipulation,希望对每对字符串应用函数,替换它们,包括列表中的字符串。例如: a = ['foo', 'bar', ['can', 'haz']] 使f(a)变成: f = lambda k,v: {'key': k, 'val': v} 上面的a仅为2维,但我对k维感兴趣。在明确用dict或其他f替换每个层次结构级别上的所有非列表元素不是它的正确用例之前,开始与一起进行黑客攻击 编辑:另一个例子 [{'key': 'foo', 'val': 'bar'}, [{'key': 'can', 'val':

希望对每对字符串应用函数,替换它们,包括列表中的字符串。例如:

a = ['foo', 'bar', ['can', 'haz']]
使
f(a)
变成:

f = lambda k,v: {'key': k, 'val': v}
上面的
a
仅为2维,但我对k维感兴趣。在明确用
dict
或其他
f
替换每个层次结构级别上的所有非列表元素不是它的正确用例之前,开始与一起进行黑客攻击

编辑:另一个例子

[{'key': 'foo', 'val': 'bar'}, [{'key': 'can', 'val': 'haz'}]]
当有一对相互相邻的时,它应该对其应用类型构造函数T,并连接(我有一个
add_to
函数支持dict、list等)任何以前的直接相邻,中间没有list inbewixt,否则原始标量应该以与以前相同的层次结构连接到列表上。以下是
g(l1)
的预期输出,不包括变量的评估:

# create some random variables, alternative: `locals().update({c: (round(…`
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = tuple(
    (round(abs(random()) ** 10, 4)
     if randint(0, 1) % 2 == 0
     else randint(20, 50)
     if randint(0, 1) % 2 == 0
     else ('foo', 'bar', 'can', 'haz', 'bzr')[randint(0, 4)])
           for c in ascii_lowercase)

l1 = [a, b, c, d, e, f, g, [h, i, j, k],
      l, m, n, [o, p, q, r, [s, t, u, v, w, x, y, z], a, b], c, d, e]

g = lambda k,v: {'{}_key'.format(k): k, '{}_val'.format(k): v}

为了支持未定义数量的级别,您将需要递归

假设您的级别在每个级别的列表中始终有2或3个项目,递归函数可能如下所示:

[
    {'a_key': a, 'a_val': b,
     'c_key': c, 'c_val': d,
     'e_key': e, 'e_val': f},
    g,
    [
        {'h_key': h, 'h_val': i,
         'j_key': j, 'j_val': k}
    ],
    {'l_key': l, 'l_val': m},
    n,
    [
        {'o_key': o, 'o_val': p,
         'q_key': q, 'q_val': r},
        [
            {'s_key': s, 's_val': t,
             'u_key': u, 'u_val': v,
             'w_key': w, 'w_val': x,
             'y_key': y, 'y_val': z}
        ],
        {'a_key': a, 'a_val': b}
    ],
    {'c_key': c, 'c_val': d},
    e
]
输出:

a = ['foo', 'bar', ['can', 'haz']]

def f(a):
    k,v,b,*_ = a+[None]
    result = [{"key":k,"val":v}]
    if b: result.append(f(b))
    return result

假设每个列表的连续内容始终是密钥对或列表:

print(f(a))

# [{'key': 'foo', 'val': 'bar'}, [{'key': 'can', 'val': 'haz'}]]


b = ['foo', 'bar', ['can', 'haz', ['boo','yah',['dino','dog']]]]
print(f(b))
[
  {'key': 'foo', 'val': 'bar'},
  [
     {'key': 'can', 'val': 'haz'},
     [
        {'key': 'boo', 'val': 'yah'},
        [
          {'key': 'dino', 'val': 'dog'}
        ]
     ]
  ]
]

更新:

好的,我必须说这让我有点头疼,但因为这是一个有趣的问题,也是学习新东西的好机会,所以它就是。
一个函数,它能做你想要的事情,而且你在递归操作方面有一些问题:


通过精确的函数和输入,我得到了递归错误:调用Python对象时超过了最大递归深度

它在不递归的情况下执行。我相信这不是最终的解决方案,但它是有效的:

a = ['foo', 'bar', ['can', 'haz']]

def f(a):
  itr = iter(a)
  return [f(a) if isinstance(x, list) else {'key': x, 'val': next(itr)} for x in itr]

# >>> f(a)
# [{'key': 'foo', 'val': 'bar'}, [{'key': 'can', 'val': 'haz'}]]


一,。如果您只是将列表列表传递给函数,我不太确定您在输出示例中应该如何知道dict键的确切前缀,所以我将把它留给您。

下面有一堆乱七八糟的东西,但是
solution()
中的核心算法看起来并没有那么糟糕。我不能说我喜欢那里的哨兵,但是。。。它使其他一切都井然有序

导入工具
进口itertools
随机输入
导入字符串
导入属性
导入工具Z
@属性(冻结=真)
课堂示例:
source=attr.ib()
target=attr.ib()
group_handler=attr.ib()
def random_示例():
a、 b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z=元组(
(圆形(abs(random.random())**10,4)
如果random.randint(0,1)%2==0
else random.randint(20,50)
如果random.randint(0,1)%2==0
else('foo','bar','can','haz','bzr')[random.randint(0,4)])
用于字符串中的c。ascii(小写)
l1=[a,b,c,d,e,f,g[h,i,j,k],
l、 m,n,[o,p,q,r,[s,t,u,v,w,x,y,z],a,b],c,d,e]
auughghhh=[
{f'{a}{u key:a,f'{a}{u val:b,
f'{c}{U key':c,f'{c}{U val':d,
f'{e}{u key':e,f'{e}{u val':f},
G
[
{f'{h}{u key:h,f'{h}{u val:i,
f'{j}{u key':j,f'{j}{u val':k}
],
{f'{l}{u key':l,f'{l}{u val':m},
N
[
{f'{o}{u key:o,f'{o}{u val:p,
f'{q}{u key':q,f'{q}{u val':r},
[
{f'{s}{u key:s,f'{s}{u val:t,
f'{u}{u key':u,f'{u}{u val':v,
f'{w}{u key':w,f'{w}{u val':x,
f'{y}{u key':y,f'{y}{u val':z}
],
{f'{a}{u key:a,f'{a}{u val:b}
],
{f'{c}{u key':c,f'{c}{u val':d},
E
]
g=lambda k,v:{{}}键。格式(k):k,{}值。格式(k):v}
返回示例(
源=l1,
目标=auauughghhh,
group\U handler=functools.partial(进程组,成对序列\U handler=lambda s:build\u dict\u by\u update(s,g)),
)
def过程组(组、成对序列处理程序):
已处理组=[]
如果len(组)==0:
返回已处理的\u组
奇数=(len(组)%2)!=0
原始对=组[:-1]如果为奇数,则为其他组
pairs=toolz.partition\u all(2个,原始\u对)
结果=成对的序列处理程序(成对)
已处理组。追加(结果)
如果为奇数:
已处理组。追加(组[-1])
返回已处理的\u组
def build dict by更新(序列、配对处理程序):
结果={}
对于按顺序排列的配对:
结果.更新(配对处理程序(*配对))
返回结果
示例=[
范例(
来源=['foo'、'bar'、['can'、'haz']],
target=[{'key':'foo','val':'bar'},[{'key':'can','val':'haz'}]],
group_handler=functools.partial(进程组,成对序列_handler=lambda s:build_dict_by_update(s,lambda k,v:{'key':k,'val':v})),
),
随机_示例(),
]
def解决方案(来源、组处理程序):
内置=[]
组=[]
sentinel=对象()
对于itertools.chain(来源[sentinel])中的值:
如果不存在(值、列表)且值不是sentinel:
group.append(值)
持续
build.extend(组\处理程序(组))
组=[]
如果值为sentinel:
打破
结果=解决方案(
来源=价值,
组处理程序=组处理程序,
)
build.append(结果)
返修
例如,在示例中:
结果=解决方案(
source=example.source,
group\u handler=example.group\u handler,
)
成功=结果==example.target
打印(“?”,已成功)
如果未成功:
打印(“?”,例如.target)
打印(“?”,结果)

这些值是否总是成对出现,并且总是按
['key1','val1']
成对排序?是的。当你想要把它推到层次结构的末尾,而不是解析它。这种方法可以从一块处理不同级别的数据结构
from functools import reduce
import operator

def traverse(lst):
  stack = [lst]
  res = [[]]

  substack = stack[0]
  subres = res[0]

  depth = 0

  while stack:
    if substack:
      if isinstance(substack[0], list):
        substack = substack[0]
        subres.append([])
        subres = subres[-1]
        depth += 1
      else:
        if len(substack) > 1 and not isinstance(substack[1], list):
            subres.append({'key': substack.pop(0), 'val': substack.pop(0)})
        else:
          subres.append(substack.pop(0))
    else:
        substack = reduce(operator.getitem, [0] * depth, stack)
        subres = reduce(operator.getitem, [-1] * depth, res)
        depth -= 1
        substack.pop(0)

  return res[0]