Python 对于迭代和随时间的推移

Python 对于迭代和随时间的推移,python,python-2.7,python-3.x,Python,Python 2.7,Python 3.x,我有一个文件文本按行分割,还有两个列表,其中包含从文件文本中提取的项目。任务是创建两个列表中出现在文件文本中同一行的项的dict。这是密码 list1 = [items] ### about 114,5 kB list2 = [items] ### about 115,5 kB file_text = file text splitted by lines ### about 190,5 kB dict_one = defaultdict(set) for line in file_tex

我有一个文件文本按行分割,还有两个列表,其中包含从文件文本中提取的项目。任务是创建两个列表中出现在文件文本中同一行的项的dict。这是密码

list1 = [items] ### about 114,5 kB
list2 = [items] ### about 115,5 kB
file_text = file text splitted by lines ### about 190,5 kB


dict_one =  defaultdict(set)
for line in file_text:
    for x in list1:
        for xx in list2:
            if x in line and xx in line:
                dict_one[x].add(xx)   
print (dict_one.items())

我的问题是迭代的时间问题。有人能提出另一种方法,用更少的时间进行迭代吗。感谢当前,您正在反复检查
列表2
中的所有项目,查看
列表1
的每个值,但这些项目是否在
行中
列表1
中的当前值是否在
行中无关。通过简单地重新排列循环,并对
list1
中的每个匹配重复使用
list2
的匹配,这应该会快得多

for line in file_text:
    x_in_line = [x for x in list1 if x in line]
    if x_in_line:
        y_in_line = [y for y in list2 if y in line]
        for x in x_in_line:
            dict_one[x].update(y_in_line)
如果
file
text
有_n_uu项、
list1
\k_uu项和
list2`j项,那么您的算法的复杂度将为O(nkj),而这个算法应该只有O(n(k+j))

另一种优化方法可能是将行拆分成一组单词,但这取决于您的数据,可能有效,也可能无效

    line_as_set = set(line.split())
    x_in_line = [x for x in list1 if x in line_as_set]
或者,由于您从
file\u text
中提取了
list1
list2
中的项目,因此您可以使用用于从文件中提取单词的相同功能,并将其仅应用于当前行,而根本不使用
list1
list2

for line in file_text:
    x_in_line = extract_values_1(line)
    if x_in_line:
        y_in_line = extract_values_2(line)
        for x in x_in_line:
            dict_one[x].update(y_in_line)

如果文件中有很多短行,那么这可能比检查
list1
list2
中的所有单词要快,只需查找该特定行中出现的极少数单词。

目前,您正在反复检查
list2
中的所有项目,以获取
list1
的每个值,但是它们是否在
行中
list1
中的当前值是否在
行中无关。通过简单地重新排列循环,并对
list1
中的每个匹配重复使用
list2
的匹配,这应该会快得多

for line in file_text:
    x_in_line = [x for x in list1 if x in line]
    if x_in_line:
        y_in_line = [y for y in list2 if y in line]
        for x in x_in_line:
            dict_one[x].update(y_in_line)
如果
file
text
有_n_uu项、
list1
\k_uu项和
list2`j项,那么您的算法的复杂度将为O(nkj),而这个算法应该只有O(n(k+j))

另一种优化方法可能是将行拆分成一组单词,但这取决于您的数据,可能有效,也可能无效

    line_as_set = set(line.split())
    x_in_line = [x for x in list1 if x in line_as_set]
或者,由于您从
file\u text
中提取了
list1
list2
中的项目,因此您可以使用用于从文件中提取单词的相同功能,并将其仅应用于当前行,而根本不使用
list1
list2

for line in file_text:
    x_in_line = extract_values_1(line)
    if x_in_line:
        y_in_line = extract_values_2(line)
        for x in x_in_line:
            dict_one[x].update(y_in_line)
如果文件中有很多短行,那么这可能比检查
list1
list2
中的所有单词要快,只需查找该特定行中出现的极少数单词即可。

可以给您提供许多加快速度的次数

示例代码的一部分

 from multiprocessing import Pool

 pool = Pool(NUMBER_OF_CORES)
 pool.map()

 def f(args):
     files, list1, list2 = args
     dict_one =  defaultdict(set)
     for line in file_text:
         for x in list1:
             for xx in list2:
                 if x in line and xx in line:
                     dict_one[x].add(xx) 

if __name__ == '__main__':
    p = Pool(NUMBER_OF_CORES)
    chunk_size= len(files) //NUMBER_OF_CORES
    print(p.map(f, [(files[i*chunk_size:(i+1)*chunk_size], list1, list2) for i in range(NUMBER_OF_CORES)]))
可以给你的内核数倍的提速

示例代码的一部分

 from multiprocessing import Pool

 pool = Pool(NUMBER_OF_CORES)
 pool.map()

 def f(args):
     files, list1, list2 = args
     dict_one =  defaultdict(set)
     for line in file_text:
         for x in list1:
             for xx in list2:
                 if x in line and xx in line:
                     dict_one[x].add(xx) 

if __name__ == '__main__':
    p = Pool(NUMBER_OF_CORES)
    chunk_size= len(files) //NUMBER_OF_CORES
    print(p.map(f, [(files[i*chunk_size:(i+1)*chunk_size], list1, list2) for i in range(NUMBER_OF_CORES)]))


你能举个简单的例子吗?不是整个文件,只有几行和几项。正如我现在所理解的,每当列表中的两个项目同时出现在一行中时,您希望在dict中有一个条目?如果您分别检查每行是否包含
list1
list2
,则速度应该会更快。您将把它存储在两个布尔numpy数组中,然后执行逻辑and(
&
)。根据实际使用情况,这应该快得多。@gho,我会尝试Carsten的方法-听起来很有希望…@Carsten,你能用一个答案来表述它吗?这是纯文本搜索吗?样本数据将非常有用。无论如何,您可以考虑从两个输入列表中创建一个正则表达式。这需要一段时间来构建,但应该执行得更快。您能提供一个简单的示例吗?不是整个文件,只有几行和几项。正如我现在所理解的,每当列表中的两个项目同时出现在一行中时,您希望在dict中有一个条目?如果您分别检查每行是否包含
list1
list2
,则速度应该会更快。您将把它存储在两个布尔numpy数组中,然后执行逻辑and(
&
)。根据实际使用情况,这应该快得多。@gho,我会尝试Carsten的方法-听起来很有希望…@Carsten,你能用一个答案来表述它吗?这是纯文本搜索吗?样本数据将非常有用。无论如何,您可以考虑从两个输入列表中创建一个正则表达式。在我的例子中,由于这两个列表的项都是从文件文本中提取的,因此x_In_line=[x for x In list1 if x In line]=x_In_line我的意思是x_In_line和y_In_line都是从同一个文件中提取的术语,因此您的[x for x In list1 if x In line] = list1@gho请注意,列表
x_in_line
将只包含当前行中的项目,而
list1
list2
包含在整个文件中某处找到的项目。@gho那么,这对您有用吗?输出是否不是您所期望的,或者它仍然不够快?在我的例子中,它仍然不够快,因为两个列表的项目都是从文件文本中提取的,所以x_in_line=[x for x in list1 if x in line]=x_in_line我的意思是x_in_line和y_in_line都是从同一文件中提取的术语,因此[x代表列表1中的x,如果x在行中] = list1@gho请注意,列表
x_in_line
将只包含当前行中的项目,而
list1
list2
包含在整个文件中某处找到的项目。@gho那么,这对您有用吗?输出是否不是您所期望的,或者它仍然不够快?它仍然不够快但这并不能减少t