如果key是相同的,则Python追加字段

时间:2017-11-30 03:57:06

标签: python

大家好我有2个名单

a = [{'employee_name': 'A', 'total_duration': 0,}, 
{'employee_name': 'B', 'total_duration': 11.0}, 
{'employee_name': 'C', 'total_duration': 9.0}, 
{'employee_name': 'D', 'total_duration':4.0,}, 
{'employee_name': 'E', 'total_duration': 0}]

b = [{'employee_name': 'A', 'actual_duration': 28}, 
{'employee_name': 'C', 'actual_duration': 22}, 
{'employee_name': 'D', 'actual_duration': 15}]

我想要的输出是:

c = [{'employee_name': 'A', 'total_duration': 0, 'actual_duration': 28}, 
    {'employee_name': 'B', 'total_duration': 11.0 'actual_duration': 0}, 
    {'employee_name': 'C', 'total_duration': 9.0, 'actual_duration': 22}, 
    {'employee_name': 'D', 'total_duration':4.0, 'actual_duration': 15}, 
    {'employee_name': 'E', 'total_duration': 0 'actual_duration': 0}]

我的问题是如何比较这2个列表,对于列表b中的每个员工,列表中的{a} {}}附加到列表中的actual_duration以及不追加{{1}的员工}

我试过

actual_duration : 0

但它不起作用,非常感谢任何帮助

4 个答案:

答案 0 :(得分:3)

正如塞巴斯蒂安所说is ==没有意义。您可以使用==测试来执行此任务,但它需要一个双for循环:在内循环中,您必须搜索b以查找匹配的条目a列表中的当前dict,如果找不到匹配项,则意味着您要搜索整个b列表。

此外,您不希望在此处执行a.append:这会在a列表中添加新项目,但您实际上想要修改a中的现有项目。

执行此操作的有效方法是首先创建一个新的dict来保存b中的数据,以便我们可以通过'employee_name'字符串查找'actual_duration'。

当我们遍历a列表时,我们使用.get方法从temp dict中检索'actual_duration',所以如果我们找不到匹配的条目然后我们将a中的'actual_duration'设置为默认值零。

a = [{'employee_name': 'A', 'total_duration': 0,}, 
{'employee_name': 'B', 'total_duration': 11.0}, 
{'employee_name': 'C', 'total_duration': 9.0}, 
{'employee_name': 'D', 'total_duration':4.0,}, 
{'employee_name': 'E', 'total_duration': 0}]

b = [{'employee_name': 'A', 'actual_duration': 28}, 
{'employee_name': 'C', 'actual_duration': 22}, 
{'employee_name': 'D', 'actual_duration': 15}]

temp = {d['employee_name']: d['actual_duration'] for d in b}

for emp in a:
    emp['actual_duration'] = temp.get(emp['employee_name'], 0)

for row in a:
    print(row)

<强>输出

{'employee_name': 'A', 'total_duration': 0, 'actual_duration': 28}
{'employee_name': 'B', 'total_duration': 11.0, 'actual_duration': 0}
{'employee_name': 'C', 'total_duration': 9.0, 'actual_duration': 22}
{'employee_name': 'D', 'total_duration': 4.0, 'actual_duration': 15}
{'employee_name': 'E', 'total_duration': 0, 'actual_duration': 0}

答案 1 :(得分:2)

employee_name根本没有意义,因为这两者都是比较。此外,由于a是列表,因此它不具有名为a的属性。您必须要求for循环遍历列表total_duration中的员工,将b的值修改为列表b中的任何值,如果不在列表{{1}中则修改为0 }}。我说最好创建一个新列表c,以避免在迭代时修改a

c = []
for index, a_dict in enumerate(a):  
    b_equivalent = next((b_dict['actual_duration'] for b_dict in b if b_dict['employee_name'] == a_dict['employee_name']), 0)
    c.append({'employee_name': a_dict['employee_name'], 'actual_duration': b_equivalent})

请注意,您使用完全错误的字典。你应该有一个employee name:duration映射,所以a只是一个字典而不是一个字典列表:

>>> employee_durations = {a_dict['employee_name']:a_dict['total_duration'] for a_dict in a}
>>> employee_durations
{'A': 0, 'B': 11.0, 'C': 9.0, 'D': 4.0, 'E': 0}

如果我们对两个列表执行此操作,我们的代码将会更加快速且不那么难看:

total_durations = {a_dict['employee_name']:a_dict['total_duration'] for a_dict in a}
actual_durations = {b_dict['employee_name']:b_dict['actual_duration'] for b_dict in b}
adjusted_durations = {}
for name in total_durations:
    adjusted_durations.update({name: actual_durations.get(name, 0)})

事实上,这可以归结为单行:

adjusted_durations = {name:actual_durations.get(name, 0) for name in total_durations}

答案 2 :(得分:0)

我认为@PM 2Ring有正确的想法 - 将数据转换为字典。然后总结持续时间很容易。

我将如何做到这一点:

total_durations = {i['employee_name']: i['total_duration'] for i in a}
actual_durations = {i['employee_name']: i['actual_duration'] for i in b}

for emp, duration in actual_durations.items():
    total_durations[emp] = total_durations.get(emp, 0) + duration

print(total_durations)

输出:

{'A': 28, 'B': 11.0, 'C': 31.0, 'D': 19.0, 'E': 0}

答案 3 :(得分:0)

你可以试试这个:

[{'actual_duration': 28, 'total_duration': 0, 'employee_name': 'A'}, {'actual_duration': 0, 'total_duration': 11.0, 'employee_name': 'B'}, {'actual_duration': 22, 'total_duration': 9.0, 'employee_name': 'C'}, {'actual_duration': 15, 'total_duration': 4.0, 'employee_name': 'D'}, {'actual_duration': 0, 'total_duration': 0, 'employee_name': 'E'}]

输出:

public function update(Post $post)
{
    //
    $data = request()->validate([
        'body' => 'required|string'
    ]);
    $this->authorize('update', $post);
    $post->update($data);
    $data['id'] = $post->id;
    $data['updatedAt'] = $post->updated_at->diffForHumans();
    $response = new Response(json_encode($data));
    $response->headers->set('Content-Type', 'application/json'); 

    return $response;

}

public function getPosts()
{
    $posts = Post::with('user')
                 ->with(['likes' => function ($query) {
                            $query->whereNull('deleted_at');
                            $query->where('user_id', auth()->user()->id);
                        }])
                    ->get();
    $response = new Response(json_encode($posts));
    $response->headers->set('Content-Type', 'application/json'); 


    $data = $posts->map(function(Post $post)
    { 
        $user = auth()->user();

        if($user->can('delete', $post)) {
            $post['deletable'] = true;
        }

        if($user->can('update', $post)) {
            $post['update'] = true;
        }

        $post['likedByMe'] = $post->likes->count() == 0 ? false : true;
        $post['likesCount'] = Like::where('post_id', $post->id)->get()->count();
        $post['createdAt'] = $post->created_at->diffForHumans();
        $data['updatedAt'] = $post->updated_at->diffForHumans();
        return $post;
    });

    return response()->json($data); 
}