根据特定键值组合字典列表

时间:2018-08-20 16:23:12

标签: python list dictionary merge

我是Python的新手,我正在尝试通过脚本解决此问题。

我有2个字典列表,如下所示:

en_list = [{'time': 840, 'text': "I want to introduce you to some\nvery wise kids that I've known,"}, 
           {'time': 5480, 'text': 'but first I want\nto introduce you to a camel.'}, 
           {'time': 8720, 'text': 'This is Cassie, a therapy camel\nvisiting one of our young patients'}, 
           {'time': 13000, 'text': 'in her room,'},
           {'time': 14920, 'text': 'which is pretty magical.'}]

fr_list = [{'time': 840, 'text': "Je veux vous présenter certains enfants\ntrès sages que j'ai rencontrés,"},
           {'time': 5480, 'text': 'mais je veux commencer\npar vous présenter un chameau.'},
           {'time': 8720, 'text': 'Voici Cassie, un chameau thérapeutique qui\nrend visite à une de nos jeunes patients'},
           {'time': 14920, 'text': 'ce qui est plutôt magique.'}]

我想创建一个仅包含“时间”键值的新列表。

我想到了这一点,但是显然,它没有考虑时间键,尽管如果两个列表具有相同数量的字典,它就可以正常工作。

for i, m in enumerate(zip(en_list, fr_list), start=1):
    print(i, m[0], "=", m[1])

这将打印出以下内容:

1 {'time': 840, 'text': "I want to introduce you to some\nvery wise kids that I've known,"} = {'time': 840, 'text': "Je veux vous présenter certains enfants\ntrès sages que j'ai rencontrés,"}
2 {'time': 5480, 'text': 'but first I want\nto introduce you to a camel.'} = {'time': 5480, 'text': 'mais je veux commencer\npar vous présenter un chameau.'}
3 {'time': 8720, 'text': 'This is Cassie, a therapy camel\nvisiting one of our young patients'} = {'time': 8720, 'text': 'Voici Cassie, un chameau thérapeutique qui\nrend visite à une de nos jeunes patients'}
4 {'time': 13000, 'text': 'in her room,'} = {'time': 14920, 'text': 'ce qui est plutôt magique.'}

如您所见,尽管英语列表同时具有正确的文本,但它错误地将'time': 13000的英语映射到'time': 14920的法语,但是上面的代码忽略了它。

所需的输出应包括所有具有“ time”键匹配值的项目,并忽略不匹配的项目。我该如何实现?

提前感谢您的支持!

3 个答案:

答案 0 :(得分:0)

从每个字典中创建一个列表,包括所有time值。找到两个列表共有的时间(创建另一个列表)。遍历此常见时间列表,从两个列表的每一个中打印相应的字典。

每个步骤都是教程和其他Stack Overflow问题中介绍的常见编程技术。编码留给学生练习。

答案 1 :(得分:0)

                //Send request to TSA Server with Curl
            if(extension_loaded('curl')) {
                $hdaLog .= "\nCurl was already Loaded\nCurl is sending tsRequest to \"".$this->timestamp_url."\"";
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $this->timestamp_url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_USERAGENT, '1');
                curl_setopt($ch, CURLOPT_POSTFIELDS, $raw_data);

                $tsResponse = curl_exec($ch);
                if($tsResponse != false) {
                    $hdaLog .= "\ntsRequest is sent";
                } else {
                    hdaLog("$hdaLog\ncan't send tsRequest, Timestamp failed",'w');
                }
                //parse ts response
                $hexTs = bin2hex($tsResponse);
                $tsparse = asn1parse($hexTs);
                $tsparse0 = asn1parse($tsparse[0][1]);
                if(count($tsparse0 > 1)) { //Remove response status data, only take timeStampToken
                    $timeStamp = seq($tsparse0[1][1]);
                } else {
                    $timeStamp = seq($tsparse0[0][1]);
                }

                //Add timestamp to TCPDF Signature
                $timeStamp = seq("060B2A864886F70D010910020E".set($timeStamp));
                $pkcs7 = int($pa1[0][1]).seq($pa1[1][1]).seq($pa1[2][1]).explicit(0, $pa1[3][1]).seq($pa1[4][1]).oct($pa1[5][1]);
                $time = seq($pkcs7.explicit(1,$timeStamp));
                $aa=seq(int(1). set($p3[1][1]).seq($p3[2][1]).explicit(0, $p3[3][1]).set($time));
                $hdaSignature = seq("06092A864886F70D010702".explicit(0,($aa)))."0000";

                $signature = $hdaSignature;
                hdaLog("$hdaLog\nTimestamp Success");
            } else {
                $hdaLog .= "\nCurl was not loaded, trying to load it...";
                if(@dl('php_curl.dll')) {
                    $hdaLog .= "\nCurl successfully Loaded";
                } else {
                    hdaLog("$hdaLog\nCurl failed to load timestamping failed", 'w');
                }
            }

(已编辑):也许可以使用

list(filter(lambda item: item[0].get('time') == item[1].get('time'), zip(en_list, fr_list)))

答案 2 :(得分:0)

您说的您的解决方案没有考虑时间值。为了为此制定一个可行的解决方案,我们需要获取每个列表的时间值,找出它们共有的时间值,然后根据常见的时间值过滤原始列表。

# Make set of time values for given list.
get_times = lambda l: {d['time'] for d in l}
# Intersection of sets
times_shared = get_times(en_list) & get_times(fr_list)

# Get dicts whose time value is shared.
get_shared = lambda l: [d for d in l if d['time'] in times_shared]

for i, m in enumerate(zip(get_shared(en_list), get_shared(fr_list)), start=1):
    print(i, m[0], '=', m[1])

或者您可以先将列表转换成字典(成对的time: text),这样会更加简单:

makedict = lambda l: {d['time']: d['text'] for d in l}
en_dict = makedict(en_list)
fr_dict = makedict(fr_list)

# Intersection
times_shared = set(en_dict) & set(fr_dict)

for i, time in enumerate(times_shared, start=1):
    print('%d %d %r = %r' % (i, time, en_dict[time], fr_dict[time]))