【问题标题】:replace all word occurrence in list with index of items in another list用另一个列表中的项目索引替换列表中出现的所有单词
【发布时间】:2017-07-09 14:54:16
【问题描述】:

我有一个清单 -

A=["hi how are you","have good day","where are you going ","do you like the place"]

和另一个列表 -

B=["how","good","where","going","like","place"]

列表 B 包含列表 A 中存在的一些单词。 我想用列表 B 中的索引替换列表 B 中出现在列表 A 中的所有单词。如果单词不存在,则将其替换为 0

所以替换后的列表A应该是

["0 1 0 0","0 2 0","3 0 0 4","0 0 5 0 6"]

我尝试使用 for 循环,但它不是有效的,因为我的列表长度 > 10000。我也尝试使用 map 函数,但我没有成功

这是我的尝试:

for item in list_A:
    words=sorted(item.split(), key=len,reverse=True)
    for w in word:
        if w.strip() in list_B:
            item=item.replace(w,str(list_B.index(w.strip())))
        else:
            item=item.replace(w,0)

【问题讨论】:

  • 你自己尝试过吗?
  • 这听起来很像家庭作业。如果是这样,最好在您的帖子中的某处提及这一点。目前,看起来您只是在要求人们为您完成工作。相关 - How do I ask and answer homework questions?
  • 我只能使用 for 循环。我也尝试使用地图功能,但没有成功。不,这不是家庭作业,这是我正在实施的程序所需要的方法
  • 完成了,您可以发布您的尝试吗?
  • @cgte for loop 解决方案已发布

标签: python list replace


【解决方案1】:

您可以做的是创建一个字典,将列表 B 中的每个单词映射到它的索引。然后你只需要遍历第一个列表一次。

类似

B = ["how","yes"]
BDict = {}
index = 0
for x in B:
    Bdict[x] = index
    index += 1

for sentence in A:
     for word in sentence:
         if word in BDict:
              #BDict[word] has the index of the current word in B
         else:
              #Word does not exist in B

这应该会显着减少运行时间,因为字典的访问时间为 O(1)。但是,根据 B 的大小,字典可能会变得非常大

编辑: 您的代码有效,之所以慢是因为inindex 运算符在您使用列表时必须执行线性搜索。因此,如果 B 变大,这可能会大大减速。然而,字典有一个恒定的时间来查看字典中是否存在键并检索值。通过使用字典,您可以将 2 O(n) 操作替换为 O(1) 操作。

【讨论】:

    【解决方案2】:

    你应该定义一个函数来返回第二个列表中单词的索引:

    def get_index_of_word(word):
        try:
            return str(B.index(word) + 1)
        except ValueError:
            return '0'
    

    然后,您可以使用嵌套列表推导生成结果:

    [' '.join(get_index_of_word(word) for word in sentence.split()) for sentence in A]
    

    更新

    from collections import defaultdict
    
    index = defaultdict(lambda: 0, ((word, index) for index, word in enumerate(B, 1))
    
    [' '.join(str(index[word]) for word in sentence.split()) for sentence in A]
    

    【讨论】:

    • 这不会减少运行时间,因为索引查找操作仍然是 O(n)
    • @GarriganStafford 你可以实现一个返回 O(1) 中单词索引的函数。我只是为了展示如何使用列表推导来生成结果。
    • 是的,但 OP 有一个正确的解决方案,并要求使其更快。我同意创建函数然后列表推导看起来更好并且更具可读性
    • @GarriganStafford 更新是否满足您的要求?
    • 是的,应该更快
    【解决方案3】:

    你可以试试这个:

    A=["hi how are you","have good day","where are you going ","do you like the place"]
    A = map(lambda x:x.split(), A)
    B=["how","good","where","going","like","place"]
    new = [[c if d == a else 0 for c, d in enumerate(i)] for i in A for a in B]
    
    final = map(' '.join, map(lambda x: [str(i) for i in x], new))
    
    print final
    

    【讨论】:

      【解决方案4】:

      您好,您的解决方案正在(过多)进行查找。

      这是我的:

      A=["hi how are you",
         "have good day",
         "where are you going ",
         "do you like the place"]
      
      B=["how","good","where","going","like","place"]
      
      # I assume B contains only unique elements.
      
      gg = { word: idx for (idx, word) in enumerate(B, start=1)}
      print(gg)
      
      lookup = lambda word: str(gg.get(word, 0)) # Buils your index and gets you efficient search with proper object types.
      
      def translate(str_):
          return ' '.join(lookup(word) for word in str_.split())        
      
      print(translate("hi how are you")) # check for one sentence.
      
      
      translated =  [translate(sentence) for sentence in A] # yey victory.
      
      print(translated)
      
      # Advanced usage
      
      class  missingdict(dict):
          def __missing__(self, key):
              return 0
      
      miss = missingdict(gg)
      
      def tr2(str_):
          return ' '.join(str(miss[word]) for word in str_.split())
      
      
      print([tr2(sentence) for sentence in A])
      

      当你对 python 更加自信时,你也可以使用 yield 关键字。

      【讨论】:

        【解决方案5】:

        这是在 Python 3.x 中

        A=["hi how are you","have good day","where are you going ","do you like the place"]
        B=["how","good","where","going","like","place"]
        list(map(' '.join, map(lambda x:[str(B.index(i)+1) if i in B else '0' for i in x], [i.split() for i in A])))
        

        输出:

        ['0 1 0 0', '0 2 0', '3 0 0 4', '0 0 5 0 6']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-08-22
          • 1970-01-01
          • 2013-03-17
          • 2019-12-24
          • 2022-07-18
          • 2021-02-10
          • 1970-01-01
          相关资源
          最近更新 更多