比较大型列表中的字符串,但不能在Python中使用set

时间:2018-07-05 10:52:25

标签: python performance nlp list-comprehension string-comparison

我有一个文本文件,其中包含11965个条目,如下所示:

AAA
BBB
CCC
DDD

Which I transformed into:
list_1 = ['AAA', 'BBB', 'CCC', ...]

我需要将它与另一个具有2221545条目的文本文件进行比较,如下所示:

AAA,.ADJ UK
AAA,.N UK
AAA,.N ES
B,.ADV UK
BB,.ADV UK
BBB,.N IT

Which I transformed into:
list_2 = ['AAA\tADJ\tUK', 'AAA\tN\tUK', 'AAA\tN\tES', 'B\tADV\UK', 'BB\tADV\tUK', ...]

所以我必须得到一个像这样的字典:

result_dict = {'AAA':[[UK, ADJ, N], [ES,N]], 'BBB':[[IT,N]], ...}

由于第二个列表的大小,如果我们一一比较条目,则时间复杂度将为O(11965*2221545)。 (我说得对吗?)

并且因为我必须获取整个条目,所以不能使用set来比较它们。有什么有效的方法可以完成工作吗?

3 个答案:

答案 0 :(得分:2)

因此,这里还有一个答案是使用defaultdict。我的走得更远,使用我在评论中给出的结果格式,并在线性时间内工作。

list_2 = ['AAA\tADJ\tUK', 'AAA\tN\tUK', 'AAA\tN\tES', 'B\tADV\tUK', 'BB\tADV\tUK']

import collections

d = collections.defaultdict(lambda: collections.defaultdict(list))

for line in list_2:
    word, wordtype, lang = line.split('\t')
    d[word][lang].append(wordtype)

d

defaultdict(<function __main__.<lambda>>,
            {'AAA': defaultdict(list, {'ES': ['N'], 'UK': ['ADJ', 'N']}),
             'B': defaultdict(list, {'UK': ['ADV']}),
             'BB': defaultdict(list, {'UK': ['ADV']})})

我们可以像这样转换为标准字典:

{k: dict(v) for k, v in d.items()}

# {'AAA': {'ES': ['N'], 'UK': ['ADJ', 'N']},
#  'B': {'UK': ['ADV']},
#  'BB': {'UK': ['ADV']}}

我们只需执行以下操作即可访问单词/语言组合

d['AAA']['UK']
# --> ['ADJ', 'N']

答案 1 :(得分:0)

以下是不需要设置的解决方案:

result_dict = {}

for item in list_1:
    result_dict.setdefault(key, [])

for item in list_2:
    value_list = item.split('\t')
    key, values = value_list[0], value_list[1:]
    result_dict.setdefault(key, []).append(values)

print result_dict
# {'B': [['ADV\\UK']], 'AAA': [['ADJ', 'UK'], ['N', 'UK'], ['N', 'ES']], 'BB': [['ADV', 'UK']]}

复杂度在列表的总长度上是线性的。

答案 2 :(得分:0)

我在评论中说的话的执行。我看不到第一个文件在哪里播放。

list_2 = ['AAA\tADJ\tUK', 'AAA\tN\tUK', 'AAA\tN\tES', 'B\tADV\tUK', 'BB\tADV\tUK']

from collections import defaultdict
collect_dict = defaultdict(lambda: defaultdict(list))
for line in list_2:
    word, pos, country = line.split()
    collect_dict[word][country].append(pos)
result_dict = { word: [[country] + poss for country, poss in country_pos.items()]
                for word, country_pos in collect_dict.items()}
# => {'AAA': [['UK', 'ADJ', 'N'], ['ES', 'N']], 'B': [['UK', 'ADV']], 'BB': [['UK', 'ADV']]}

编辑:我实际上同意FHTMitchell的评论-仅当您确实喜欢问题中发布的格式时才进行最后的转换,但是collect_dict中的格式可能更有用。

编辑:基于注释中的澄清(列表1用于限制list2的元素):

list_2 = ['AAA\tADJ\tUK', 'AAA\tN\tUK', 'AAA\tN\tES', 'B\tADV\tUK', 'BB\tADV\tUK']

from collections import defaultdict
valid_set = set(list1)
collect_dict = defaultdict(lambda: defaultdict(list))
for line in list_2:
    word, pos, country = line.split()
    if word in valid_set:
        collect_dict[word][country].append(pos)
result_dict = { word: [[country] + poss for country, poss in country_pos.items()]
                for word, country_pos in collect_dict.items()}