将字符串列表传递给map_async()

3 投票
1 回答
1776 浏览
提问于 2025-04-16 20:07

我遇到了一个有趣的问题,关于map_async的用法,我搞不清楚。

我正在使用Python的多进程库,利用进程池。我想把一个字符串列表传给一个函数,用来进行比较,同时还有另一个要比较的字符串列表,使用map_async()来处理。

现在我的代码是这样的:

from multiprocessing import Pool, cpu_count
import functools

dictionary = /a/file/on/my/disk
passin = /another/file/on/my/disk

num_proc = cpu_count()

dictionary = readFiletoList(fdict)
dictionary = sortByLength(dictionary)

words = readFiletoList(passin, 'WINDOWS-1252')
words = sortByLength(words)

result = pool.map_async(functools.partial(mpmine, dictionary=dictionary), [words], 1000)

def readFiletoList(fname, fencode='utf-8'):
  linelist = list()
  with open(fname, encoding=fencode) as f:
    for line in f:
      linelist.append(line.strip())
  return linelist


def sortByLength(words):
  '''Takes an ordered iterable and sorts it based on word length'''
  return sorted(words, key=len)

def mpmine(word, dictionary):
  '''Takes a tuple of length 2 with it's arguments.

  At least dictionary needs to be sorted by word length. If not, whacky results ensue.
  '''
  results = dict()
  for pw in word:
    pwlen = len(pw)
    pwres = list()
    for word in dictionary:
      if len(word) > pwlen:
        break
      if word in pw:
        pwres.append(word)
    if len(pwres) > 0:
      results[pw] = pwres
  return results



if __name__ == '__main__':
  main()

这里的字典和单词都是字符串的列表。结果是只用了一个进程,而不是我设置的多个进程。如果我把'words'这个变量的方括号去掉,它似乎会逐个字符地遍历每个字符串,结果就乱套了。

我希望的结果是能从'words'中取出大约1000个字符串,传给工作进程,然后获取结果,因为这个任务是非常适合并行处理的。

编辑:我添加了更多代码,以便让事情变得更清楚。

1 个回答

3

好的,其实我自己解决了这个问题。我在这里发个答案,方便其他遇到同样问题的人。我的问题出在map_async这个函数上,它从列表中取出一个项目(在这里是一个字符串),然后把这个字符串传给一个函数,而这个函数其实是期待接收一个字符串列表的。所以它就把每个字符串当成了字符列表来处理。修正后的mpmine代码是:

def mpmine(word, dictionary):
  '''Takes a tuple of length 2 with it's arguments.

  At least dictionary needs to be sorted by word length. If not, whacky results ensue.
  '''
  results = dict()
  pw = word
  pwlen = len(pw)
  pwres = list()
  for word in dictionary:
    if len(word) > pwlen:
      break
    if word in pw:
      pwres.append(word)
  if len(pwres) > 0:
    results[pw] = pwres
  return results

希望这能帮助到其他遇到类似问题的人。

撰写回答