代码之家  ›  专栏  ›  技术社区  ›  shantanuo

对单词和字符进行分组和分类

  •  6
  • shantanuo  · 技术社区  · 6 年前

    我需要在斜线上分开,然后报告标签。这是拼音字典格式。我试图在github上找到一个这样做的类,但找不到。

    # vi test.txt
    test/S
    boy
    girl/SE
    home/
    house/SE123
    man/E
    country
    wind/ES
    

    代码:

    from collections import defaultdict
    myl=defaultdict(list)
    
    with open('test.txt') as f :
        for l in f:
            l = l.rstrip()
            try:
                tags = l.split('/')[1]
                myl[tags].append(l.split('/')[0])
                for t in tags:
                    myl[t].append( l.split('/')[0])
            except:
                pass
    

    输出:

    defaultdict(list,
                {'S': ['test', 'test', 'girl', 'house', 'wind'],
                 'SE': ['girl'],
                 'E': ['girl', 'house', 'man', 'man', 'wind'],
                 '': ['home'],
                 'SE123': ['house'],
                 '1': ['house'],
                 '2': ['house'],
                 '3': ['house'],
                 'ES': ['wind']})
    

    se组应该有3个单词“girl”、“wind”和“house”。不应存在ES组,因为它包含在“SE”中,并且SE123应保持原样。我怎样才能做到这一点?


    更新:

    我已经设法添加了大图,但我如何添加3,4,5克?

    from collections import defaultdict
    import nltk
    myl=defaultdict(list)
    
    with open('hi_IN.dic') as f :
        for l in f:
            l = l.rstrip()
            try:
                tags = l.split('/')[1]
                ntags=''.join(sorted(tags))
                myl[ntags].append(l.split('/')[0])
                for t in tags:
                    myl[t].append( l.split('/')[0])
                bigrm = list(nltk.bigrams([i for i in tags]))
                nlist=[x+y for x, y in bigrm]
                for t1 in nlist:
                    t1a=''.join(sorted(t1))
                    myl[t1a].append(l.split('/')[0])
            except:
                pass
    

    我想如果我在源代码处对标签进行排序会有帮助:

    with open('test1.txt', 'w') as nf:
        with open('test.txt') as f :
            for l in f:
                l = l.rstrip()
                try:
                    tags = l.split('/')[1]
                except IndexError:
                    nline= l 
                else:
                    ntags=''.join(sorted(tags))
                    nline= l.split('/')[0] + '/' + ntags
                nf.write(nline+'\n')
    

    这将创建一个带有排序标记的新文件test1.txt。但是三联图+的问题仍然没有解决。


    我下载了一个示例文件:

    !小精灵 https://raw.githubusercontent.com/wooorm/dictionaries/master/dictionaries/en-US/index.dic

    使用“grep”命令的报告是正确的。

    !grep 'P.*U' index1.dic
    
    CPU/M
    GPU
    aware/PU
    cleanly/PRTU
    common/PRTUY
    conscious/PUY
    easy/PRTU
    faithful/PUY
    friendly/PRTU
    godly/PRTU
    grateful/PUY
    happy/PRTU
    healthy/PRTU
    holy/PRTU
    kind/PRTUY
    lawful/PUY
    likely/PRTU
    lucky/PRTU
    natural/PUY
    obtrusive/PUY
    pleasant/PTUY
    prepared/PU
    reasonable/PU
    responsive/PUY
    righteous/PU
    scrupulous/PUY
    seemly/PRTU
    selfish/PUY
    timely/PRTU
    truthful/PUY
    wary/PRTU
    wholesome/PU
    willing/PUY
    worldly/PTU
    worthy/PRTU
    

    对排序标记文件使用bigrams的python报告不包含上述所有单词。

    myl['PU']
    
    ['aware',
     'aware',
     'conscious',
     'faithful',
     'grateful',
     'lawful',
     'natural',
     'obtrusive',
     'prepared',
     'prepared',
     'reasonable',
     'reasonable',
     'responsive',
     'righteous',
     'righteous',
     'scrupulous',
     'selfish',
     'truthful',
     'wholesome',
     'wholesome',
     'willing']
    
    3 回复  |  直到 6 年前
        1
  •  5
  •   willeM_ Van Onsem    6 年前

    如果我理解正确,这更多的是构建一个数据结构,对于一个给定的标记, 建构 正确的列表。我们可以通过构造一个只考虑单数标记的字典来做到这一点。稍后,当一个人查询多个标记时,我们计算交集。这使得它能够简洁地表示,并且很容易地提取例如带有标记的所有元素 AC 这将列出带有标记的元素 ABCD , ACD , ZABC 等。

    因此,我们可以构造一个解析器:

    from collections import defaultdict
    
    class Hunspell(object):
    
        def __init__(self, data):
            self.data = data
    
        def __getitem__(self, tags):
            if not tags:
                return self.data.get(None, [])
    
            elements = [self.data.get(tag ,()) for tag in tags]
            data = set.intersection(*map(set, elements))
            return [e for e in self.data.get(tags[0], ()) if e in data]
    
        @staticmethod
        def load(f):
           data = defaultdict(list)
           for line in f:
               try:
                   element, tags = line.rstrip().split('/', 1)
                   for tag in tags:
                       data[tag].append(element)
                   data[None].append(element)
               except ValueError:
                   pass  # element with no tags
           return Hunspell(dict(data))
    

    结束时的列表处理 __getitem__ 以正确的顺序检索元素。

    然后,我们可以使用以下命令将文件加载到内存中:

    >>> with open('test.txt') as f:
    ...     h = Hunspell.load(f)
    

    并查询任意键:

    >>> h['SE']
    ['girl', 'house', 'wind']
    >>> h['ES']
    ['girl', 'house', 'wind']
    >>> h['1']
    ['house']
    >>> h['']
    ['test', 'girl', 'home', 'house', 'man', 'wind']
    >>> h['S3']
    ['house']
    >>> h['S2']
    ['house']
    >>> h['SE2']
    ['house']
    >>> h[None]
    ['test', 'girl', 'home', 'house', 'man', 'wind']
    >>> h['4']
    []
    

    查询不存在的标记将导致空列表。因此,在这里,我们在调用时推迟了“交叉点”过程。事实上,我们已经可以生成所有可能的交叉点,但这将导致一个大型的数据结构,可能还需要大量的工作

        2
  •  2
  •   Cheche    6 年前

    试试这个:

    myl=dict()
    with open('test.txt') as f :
        for l in f:
            l = l.rstrip()
            try:
                tags = l.split('/')[1]
                myl.setdefault(tags,[])
                myl[tags].append(l.split('/')[0])
                for t in tags:
                    myl.setdefault(t,[])
                    myl[t].append( l.split('/')[0])
            except:
                pass
    keys=myl.keys()
    for k1 in keys:
        for k2 in keys:
            if len(set(k1).intersection(k2))==len(set(k1)) and k1!=k2:
                myl[k1].extend([myk2v for myk2v in myl[k2] if myk2v not in myl[k1]]) 
    print(myl)
    

    产量

    {'S': ['test', 'test', 'girl', 'house', 'wind'], 'SE': ['girl', 'house', 'wind'], 'E': ['girl', 'house', 'man', 'man', 'wind'], '': ['home', 'test', 'test', 'girl', 'house', 'wind', 'man', 'man'], 'SE123': ['house'], '1': ['house'], '2': ['house'], '3': ['house'], 'ES': ['wind', 'girl', 'house']}
    

    在程序的最后两个for循环中, k1 k2 先取,然后比较两个集合的交集。如果交叉点的长度等于集合的长度 K1 ,键的值 K2 应该在钥匙里 K1 ,所以密钥的值 K2 添加到密钥中 K1 .

        3
  •  0
  •   Pramit Sawant    6 年前

    更简单的版本 willem van onsem 已经回答了

    data = defaultdict(list)
    with open('text.txt') as f:
        for line in f.readlines():
            try:
                element,tags = line.rstrip().split('/', 1)
                print(element)
                for tag in tags:
                    data[tag].append(element)
                    data[None].append(element)
            except ValueError:
                pass
    
    def parse(data,tag):
        if(tag==None or tag==''):
            return set(data[None])
        elements = [set(data[tag_i]) for tag_i in tag]
        return set.intersection(*map(set, elements))
    
    
    
    >>> parse(data,'ES') 
    >>> {'girl', 'house', 'wind'}
    >>> parse(data,None)
    >>> {'girl', 'house', 'man', 'wind'}
    >>> parse(data,'')
    >>> {'girl', 'house', 'man', 'wind'}