为了账号安全,请及时绑定邮箱和手机立即绑定

在python中将字符串列表拆分为字典键

在python中将字符串列表拆分为字典键

眼眸繁星 2022-07-12 15:26:30
我有一个字符串'request.context.user_id',我想用'。'分割字符串 并将列表中的每个元素用作字典键。有没有办法对不同长度的列表执行此操作,而无需在拆分后尝试对所有不同可能的列表长度进行硬编码?parts = string.split('.')if len(parts)==1:    data = [x for x in logData if x[parts[0]] in listX]elif len(parts)==2:    data = [x for x in logData if x[parts[0]][parts[1]] in listX]else:    print("Add more hard code")listX 是应由 x[parts[0]][parts[1] 检索的字符串值列表 logData 是通过读取 json 文件获得的列表,然后可以使用 json_normalize 将列表读入数据帧...提供了 df 部分以提供有关其结构的一些上下文.. dicts 列表:import jsonfrom pandas.io.json import json_normalizewith open(project_root+"filename") as f:    logData = json.load(f)df = json_normalize(logData)
查看完整描述

2 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

我刚刚在评论中意识到您说您不想创建新字典,而是x通过链接列表中的部分来访问现有字典。


(3.b) 使用 afor loop获取/设置路径键中的值

如果您只想读取路径末尾的值


import copy


def get_val(key_list, dict_):

    reduced = copy.deepcopy(dict_)

    for i in range(len(key_list)):

        reduced = reduced[key_list[i]]

    return reduced


# this solution isn't mine, see the link below

def set_val(dict_, key_list, value_):

    for key in key_list[:-1]:

        dict_ = dict_.setdefault(key, {})

    dict_[key_list[-1]] = value_

get_val() 其中 key_list 是您的案例的结果,string.slit('.')并且dict_是x字典。您可以省略copy.deepcopy()部分,这只是像我这样偏执的窥视者 - 原因是 python dict 不是不可变的,因此处理deepcopy(内存中单独但精确的副本)是一种解决方案。

set_val()正如我所说,这不是我的主意,@Bakuriu

dict.setdefault(key, default_value)的功劳将处理x.

eval()(3) 使用和/或将字符串评估为代码exec()

所以这是一个丑陋的不安全解决方案:


def chainer(key_list):

    new_str = ''

    for key in key_list:

        new_str = "{}['{}']".format(new_str, key)

    return new_str


x = {'request': {'context': {'user_id': 'is this what you are looking for?'}}}

keys = 'request.context.user_id'.split('.')

chained_keys = chainer(keys)


# quite dirty but you may use eval() to evaluate a string

print( eval("x{}".format(chained_keys)) )


# will print

is this what you are looking for?

这是模型x字典的最里面的值


我假设你可以像这样在你的代码中使用它


data = [x for x in logData if eval("x{}".format(chained_keys)) in listX]

# or in python 3.x with f-string

data = [x for x in logData if eval(f"x{chained_keys}") in listX]

...或类似的东西。


类似地,exec()如果您想写入,您可以使用将字符串作为代码执行x,尽管它同样肮脏且不安全。


exec("x{} = '...or this, maybe?'".format(chained_keys))

print(x)


# will print

{'request': {'context': {'user_id': '...or this, maybe?'}}}

(2)一个实际的解决方案 可能是recursive function这样的:

def nester(key_list):

    if len(key_list) == 0:

        return 'value'   # can change this to whatever you like

    else:

        return {key_list.pop(0): nester(key_list)}


keys = 'request.context.user_id'.split('.')  

# ['request', 'context', 'user_id']


data = nester(keys)

print(data)


# will result

{'request': {'context': {'user_id': 'value'}}}

(1)用'.'分割字符串的解决list comprehension方案 并将列表中的每个元素用作字典键

data = {}

parts = 'request.context.user_id'.split('.')


if parts:   # one or more items

    [data.update({part: 'value'}) for part in parts]


print(data)


# the result

{'request': 'value', 'context': 'value', 'user_id': 'value'}

您可以在之后覆盖这些值。data


查看完整回答
反对 回复 2022-07-12
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

如果您想要任意计数,这意味着您需要一个循环。您可以get重复使用来钻取字典层。


parts = "request.context.user_id".split(".")

logData = [{"request": {"context": {"user_id": "jim"}}}]

listX = "jim"


def generate(logData, parts):

    for x in logData:

        ref = x

        # ref will be, successively, x, then the 'request' dictionary, then the

        # 'context' dictionary, then the 'user_id' value 'jim'. 

        for key in parts:

            ref = ref[key]

        if ref in listX:

            yield x



data = list(generate(logData, parts)))  # ['jim']


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 227 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号