【问题标题】:Match adjacent list elements with a list of tuples in Python将相邻的列表元素与 Python 中的元组列表匹配
【发布时间】:2014-03-13 00:20:10
【问题描述】:

我有一个文档中单个单词的有序列表,如下所示:

words = ['apple', 'orange', 'boat', 'car', 'happy', 'day', 'cow', ...]

我有第二个重要二元组/搭配的元组列表,如下所示:

bigrams = [('apple', 'orange'), ('happy', 'day'), ('big', 'house'), ...]

我想遍历单个单词的列表并用下划线分隔的二元组替换相邻的单词,最终得到如下列表:

words_fixed = ['apple_orange', 'boat', 'car', 'happy_day', 'cow', ...]

我考虑过将wordsbigrams 扁平化为字符串(" ".join(words) 等),然后使用正则表达式来查找和替换相邻的单词,但这似乎非常低效且不合Python。

从元组列表中快速匹配和组合相邻列表元素的最佳方法是什么?

【问题讨论】:

    标签: python


    【解决方案1】:

    不像@inspectorG4dget那么华丽:

    words_fixed = []
    last = None
    for word in words:
        if (last,word) in bigrams:
            words_fixed.append( "%s_%s" % (last,word) )
            last = None
        else:
            if last:
                words_fixed.append( last )
            last = word
    if last:
        words_fixed.append( last )
    

    【讨论】:

    • 太棒了。不像 itertools 版本那么华丽,但它不会改变原始的 wordsbigrams 变量。
    【解决方案2】:
    words = ['apple', 'orange', 'boat', 'car', 'happy', 'day', 'cow']
    bigrams = [('apple', 'orange'), ('happy', 'day'), ('big', 'house')]
    
    bigrams_dict = dict(item for item in bigrams)
    bigrams_dict.update(item[::-1] for item in bigrams)
    
    words_fixed = ["{}_{}".format(word, bigrams_dict[word]) 
        if word in bigrams_dict else word
        for word in words]
    

    [编辑]另一种创建字典的方法:

    from itertools import chain
    bigrams_rev = (reversed(x) for x in bigrams)
    bigrams_dict = dict(chain(bigrams, bigrams_rev))
    

    【讨论】:

    • 这最终会反转二元组,导致['apple_orange', 'orange_apple', 'boat', 'car', 'happy_day', 'day_happy', 'cow']
    • 嗯,你需要的解决方案是来自@inspectorG4dget ;)
    【解决方案3】:
    words = ['apple', 'orange', 'boat', 'car', 'happy', 'day', 'cow', ...]
    bigrams = [('apple', 'orange'), ('happy', 'day'), ('big', 'house'), ...]
    

    首先,进行一些优化:

    import collections
    bigrams = collections.defaultdict(set)
    for w1,w2 in bigrams:
        bigrams[w1].add(w2)
    

    现在,开始有趣的事情:

    import itertools
    words_fixed = []
    for w1,w2 in itertools.izip(itertools.islice(words, 0, len(words)), (itertools.islice(words, 1, len(words)))):
        if w1 in bigrams and w2 in bigrams[w1]:
            words_fixed.append("%s_%s" %(w1, w2))
    

    如果您想查看二元组中没有的单词,除了您记录在二元组中的单词,那么这应该可以解决问题:

    import itertools
    words_fixed = []
    for w1,w2 in itertools.izip(itertools.islice(words, 0, len(words)), (itertools.islice(words, 1, len(words)))):
        if w1 in bigrams and w2 in bigrams[w1]:
            words_fixed.append("%s_%s" %(w1, w2))
        else:
            words_fixed.append(w1)
    

    【讨论】:

    • 哦,这很酷,但它最终只返回连接的二元组:['apple_orange', 'happy_day']
    • 太棒了。这也真的很快。谢谢!
    • 其实差不多。仅附加 w1 有效,但它错过了最后一个单词元素,因为它存储在 w2 中。它以['apple_orange', 'orange', 'boat', 'car', 'happy_day', 'day'] 结尾,重复day 并缺少cow
    【解决方案4】:
    words = ['apple', 'orange', 'boat', 'car', 'happy', 'day', 'cow', 'big']
    bigrams = [('apple', 'orange'), ('happy', 'day'), ('big', 'house')]
    print 'words   :',words
    print 'bigrams :',bigrams
    print
    def zwii(words,bigrams):
        it = iter(words)
        dict_bigrams = dict(bigrams)
        for x in it:
            if x in dict_bigrams:
                try:
                    y = it.next()
                    if dict_bigrams[x] == y:
                        yield '-'.join((x,y))
                    else:
                        yield x
                        yield y
                except:
                    yield x
            else:
                yield x
    
    print list(zwii(words,bigrams))
    

    结果

    words   : ['apple', 'orange', 'boat', 'car', 'happy', 'day', 'cow', 'big']
    bigrams : [('apple', 'orange'), ('happy', 'day'), ('big', 'house')]
    
    ['apple-orange', 'boat', 'car', 'happy-day', 'cow', 'big']
    

    【讨论】:

      猜你喜欢
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多