Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用Python的高级映射和过滤器_Php_Python - Fatal编程技术网

Php 使用Python的高级映射和过滤器

Php 使用Python的高级映射和过滤器,php,python,Php,Python,我需要将PHP的小功能翻译成Python 我需要根据URI匹配一个JSON数据源。下面是一个数据示例: [ { "group": "fruits", "members": [ { "name": "apple", "id": 1 }, { "name": "orange",

我需要将PHP的小功能翻译成Python

我需要根据URI匹配一个JSON数据源。下面是一个数据示例:

[
    {
        "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别灰心。我相信你能想出一个比这更干净的方法。另外,这是一个很好的实践。如果你想知道的话,你会呕吐的请参阅我的嵌套循环,以获取进入列表的循环,然后进入字典,然后进入其键值对。