【问题标题】:Replacing a string by a tuple value in python在python中用元组值替换字符串
【发布时间】:2017-11-22 09:14:53
【问题描述】:

这是我在 stackoverflow 上的第一篇文章/问题!

我在尝试替换表情符号(包含在元组内的列表中)时遇到问题。代码如下:

emoticons = [('SMILE',[':-)', ':)', '(:', '(-:']),
        ('LAUGH',[':-D', ':D', 'X-D', 'XD', 'xD']),
        ('LOVE', ['<3', ':\*']),
        ('WINK', [';-)', ';)', ';-D', ';D', '(;', '(-;']),
        ('FROWN', [':-(', ':(', '(:', '(-:']),
        ('CRY', [':,(', ':\'(', ':"(', ':(('])]


def token_to_emot(token):
    for (emoji, smileys) in emoticons:
        if token in smileys:
            converted = token.replace(token, emoji)
            return converted
        else:
            return token

sample_tweet = ['It', 'was', 'amazing', ':)']
processed_tweet = [token_to_emot(token) for token in sample_tweet]
print(processed_tweet)

第一次尝试产生了预期的输出:

['It', 'was', 'amazing', 'SMILE']

但是,如果我使用剩余元组中的笑脸对其进行测试,则代码不起作用并且表情符号不会被转换。有人可以帮我找出这里的列表理解有什么问题吗?或者也许建议另一种将表情符号转换为字符串的方法? 谢谢!

【问题讨论】:

    标签: python-3.x nlp list-comprehension


    【解决方案1】:

    无论是否找到表情符号,您都会在循环的第一次迭代中返回。 相反,您应该首先完成对整个 emoticons 列表的迭代,如果没有找到替换,则只返回未转换的令牌:

    def token_to_emot(token):
        for (emoji, smileys) in emoticons:
            if token in smileys:
                converted = token.replace(token, emoji)
                return converted
    
        # Note this is AFTER the for loop is exhausted.    
        return token
    

    【讨论】:

    • 成功了!谢谢。看来我需要复习一下列表理解!
    • @bart 代码的列表理解部分很好。 token_to_emot 函数有一个错误。
    【解决方案2】:

    问题在于“else”语句

    def token_to_emot(token):
      for (emoji, smileys) in emoticons:
          if token in smileys:
              converted = token.replace(token, emoji)
              return converted
          else:
              return token
    

    如果在第一个笑脸数组中找不到笑脸,则返回令牌。

    修改为:-

    def token_to_emot(token):
      for (emoji, smileys) in emoticons:
          if token in smileys:
              converted = token.replace(token, emoji)
              return converted
      else:
          return token 
          # return token only and only if token!=smileys for all emoticons
    

    另外,你也可以使用:-

    sample_tweet = ['It', 'was', 'amazing', ':)']
    processed_tweet = list(map(token_to_emot, sample_tweet))
    

    【讨论】:

    • 谢谢!这也很好用!我尝试了不同的解决方案,但距离找到它有一个退格=]
    【解决方案3】:

    我会为此使用dictionary,因为它会运行得更快,尤其是您处理的推文越多。此外,您可以使用漂亮、可读的列表推导来大幅减少代码。

    关于速度的说明:

    1. 您当前的程序必须为字符串 (O(n)) 中的每个标记遍历每个表情符号 (O(n))。制作算法O(n^2)。从技术上讲,您的更像O(ne),其中 n 是标记的数量,e 是唯一表情符号的数量。所以,这不是字面上的 O(n^2)。但我是用这个来解释效率差异的。

    2. 但是,在我的代码中,我们必须对每个令牌进行字典检查(即O(1))。这就是我的O(n),当您处理大众推文时,这会产生很大的不同。

    代码

    emoticons = [('SMILE',[':-)', ':)', '(:', '(-:']),
            ('LAUGH',[':-D', ':D', 'X-D', 'XD', 'xD']),
            ('LOVE', ['<3', ':\*']),
            ('WINK', [';-)', ';)', ';-D', ';D', '(;', '(-;']),
            ('FROWN', [':-(', ':(', '(:', '(-:']),
            ('CRY', [':,(', ':\'(', ':"(', ':(('])]
    
    emoticonDi = {e:string for string,emoji in emoticons for e in emoji}
    
    import re
    def convert_emoji(string):
        sample_tweet = string.split(" ")
        processed_tweet = [emoticonDi[v] if v in emoticonDi else v for v in sample_tweet]
        return processed_tweet
    
    print(convert_emoji('It was amazing :)'))
    

    【讨论】:

    • 感谢代码和解释!关于原始代码是否可以改进的一些反馈也是我正在寻找的东西!
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2022-06-17
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2020-12-25
    相关资源
    最近更新 更多