Php 使用Python的高级映射和过滤器
我需要将PHP的小功能翻译成Python 我需要根据URI匹配一个JSON数据源。下面是一个数据示例:Php 使用Python的高级映射和过滤器,php,python,Php,Python,我需要将PHP的小功能翻译成Python 我需要根据URI匹配一个JSON数据源。下面是一个数据示例: [ { "group": "fruits", "members": [ { "name": "apple", "id": 1 }, { "name": "orange",
[
{
"group": "fruits",
"members": [
{
"name": "apple",
"id": 1
},
{
"name": "orange",
"id": 2
}
]
},
{
"group": "vegetables",
"members": [
{
"name": "tomato",
"id": 3
},
{
"name": "carrot",
"id": 4
}
]
},
{
"group": "candies",
"members": [
{
"name": "chocolate",
"id": 5
},
{
"name": "cookie",
"id": 6
}
]
}
]
变量中有一个URI,例如orange/carrot,它应该返回匹配对象的数组:
[
{
"name": "orange",
"id": 2
},
{
"name": "carrot",
"id": 4
}
]
它只能根据数据源顺序匹配它们,因此不接受例如胡萝卜/橙色或番茄/饼干。需要在第一个组等中找到第一个URI段。如果URI显示为无效,则结果应为空
以下是我制作的PHP版本:
$uri = 'apple/carrot';
$segments = explode('/', $uri);
$groups = json_decode(file_get_contents('data/food.json'));
$matches = array_map(function (string $segment, int $index) use ($groups): ?object {
return array_values(array_filter($groups[$index]->members, function (object $item) use ($segment): bool {
return $item->name === $segment;
}))[0] ?? null;
}, $segments, array_keys($segments));
$matches = in_array(null, $matches) ? null : $matches;
下面是我尝试使用Python所做的:
import os, json
uri = 'apple/carrot'
segments = uri.split('/')
dataFilePath = os.path.join(os.path.dirname(__file__), 'data/food.json')
groupsJSON = open(dataFilePath).read()
groups = json.loads(groupsJSON)
# Here I tried to work it out with map() and filter() or list comprehension
items = items if None not in items else None
我不知道Python的方法是什么。你们能帮我完成这个转换吗?我的建议是使用生成器:
def search_members(items, needles):
local_needles = needles.split('/')
needle = local_needles.pop(0)
all_found = False
for item in items:
for member in item['members']:
if member['name'] == needle:
yield member
if local_needles:
needle = local_needles.pop(0)
else:
all_found = True
break
if all_found:
break
我没能找到一个比这更好的时间共谋的场景
needles = 'orange/carrot'
result = list(search_members(items, needles))
例如,如果提供了错误的数据,您可以在比较两个长度后引发异常
if len(result) != len(needles):
raise Exception('Wrong data supplied for url!)
这是我对python方式的解释
import json
from typing import Optional
# uses python 3.6 type hints, feel free to remove
def func(uri: str, groups_json: str) -> Optional[str]:
segments = uri.split('/')
groups = json.loads(groups_json)
# this a dictionary comprehension with a double for loop
members = {member['name']: member
for group in groups
for member in group['members']}
# nb. this will throw a KeyError if segment is not valid --
# maybe put in try / except KeyError block?
items = [members[segment] for segment in segments]
# make sure items are in a valid order
if not sorted(items, key=lambda item: item['id']) == items:
return None
return json.dumps(items)
print(func('apple/carrot', groupsJSON))
# --> [{"name": "apple", "id": 1}, {"name": "carrot", "id": 4}]
print(func('carrot/apple', groupsJSON))
# --> None
告诉我,源JSON是以[还是以{开头?它以[.这些组是有序的。好的。正在研究一个解决方案。你能将import pandas作为pd和df=pd.read_jsony运行你的json文件路径吗?也许可以附加你看到的内容的快照?我只需要了解当你使用pd.read_jsonImporter阅读时,members列的外观。请记住,没有名为“pandas”的模块ps在这里很重要。我不认为针可以是一个集合。@Robo Robok,ok,抱歉,对问题描述不够关注。希望现在更好。我非常建议不要修改参数。针在通过此函数后将是空的。您可以始终接受字符串并自己拆分它。另外,lst.pop0是一个Olenlst操作,而索引为O1。您的缩进仍然混乱。我无法实际运行此程序。您使用四个空格,然后使用三个空格进行缩进。请按照PEP8的建议使用4。对于大型列表,pop0比pop慢1000倍:-x=listrange10**8;%timeit x.pop;128 ns±1.07 ns/循环平均±标准偏差7次,10次000000个循环每个…x=listrange10**8;%timeit x.pop0;115 ms±507µs每个循环意味着±标准偏差7次,每个循环10次。我甚至不想费心回答,因为你找到了正确的解决方案。@Abhishek别灰心。我相信你能想出一个比这更干净的方法。另外,这是一个很好的实践。如果你想知道的话,你会呕吐的请参阅我的嵌套循环,以获取进入列表的循环,然后进入字典,然后进入其键值对。