【问题标题】:Deleting a character midstring (iterable) in python在python中删除一个字符中间字符串(可迭代)
【发布时间】:2012-01-18 00:35:22
【问题描述】:

我有一长串包含 4 条信息的字符串。我通过在空白处拆分它们来索引它们。不幸的是,在一些字符串中,第二条信息中也有一个空格。我希望能够删除两个冒号之间出现的任何空格。这里从列表中的几个项目来演示:

国外a:at:n请求1

在国外 a:at:n 沉默 1

在国外 a:at:n 时间 6

国外a:because of:n schedule 1

国外a:by:n 美国1

国外a:by:n银行1

国外a:by:n吹1

所以,我的问题出现在上面的第 4 行。显然我可以手动删除空间来解决问题,但列表是数千行。另外,我可以编写代码,用“becauseof”替换任何出现的“because of”,但这并不是唯一出现的两个单词序列。此外,第三个切片有时包含“因为”,我想在那里保留空格。我当前的代码试图返回每个序列的频率,如下所示:

import sys
import pprint

occ_list = []
observed = {}

lines = sys.stdin.readlines()

for line in lines:
    l = line.strip()
    i = l.split(' ')
    word = i[0]
    rel = i[1]
    wirts = i[2:-1]
    wirt = ' '.join(wirts)  # Word-in-relation-to (which may be compund)
    occ = i[-1]             # Frequency of specific "word, rel, wirt"
    arb = (word, rel, wirt)
    occ_list.append(int(occ))

    if not arb in observed.keys():
            observed[arb] = []
    if not occ in observed[arb]:
            observed[arb].append(int(occ)/float(1064542))

pprint.pprint(observed)

除了前面提到的带有额外空格的行之外,这有效。

如果有任何建议,我将不胜感激。 (我正在使用python 3.2) 谢谢

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    从在空白处拆分开始。如果第二项 包含空格,那么其中应该有 2 个冒号;如果只有一个冒号,则第二项中有 空格,因此第二项和第三项是单个项的一部分。

    parts = line.split()
    if parts[1].count(":") == 1:
        parts[1 : 3] = [" ".join(parts[1 : 3])]
    

    【讨论】:

      【解决方案2】:

      除了第二位信息中的冒号之外,您是否希望文本文件中还有冒号?如果不是,我建议拆分冒号以删除空格。但是,如果您想在其他信息中允许使用其他冒号,那么我建议使用 re (regex) 模块。

      # Split on colons:
      bits = l.split(':')
      # remove spaces in the second part
      bits[1] = bits[1].replace(' ','')
      # join again
      l = ':'.join(bits)
      # do rest of code.
      

      另外,我认为您在问题中提到了这一点,但我想澄清一下。你有这样的台词吗?

      abroad a:by:because of american 1
      

      在这种情况下,您是否希望 rel 成为 a:by:because of

      信息第 3 部分 (wirts) 可以是多个单词吗?怎么样:

      abroad a:by:because of american silence 2
      

      你将如何计算出哪些词属于哪些词?

      在这种情况下,我认为您需要有一个包含a:by:xxxx 中允许的空格的单词字典。

      【讨论】:

        【解决方案3】:

        使用正则表达式:

        #!/usr/bin/env python
        import fileinput
        import re
        from collections import defaultdict
        from pprint import pprint
        
        occ_list = []
        observed = defaultdict(list)
        for line in fileinput.input():
            m = re.search(r"(\S+)\s+([^:]+:[^:]+:\S+)\s+(\S+)\s+(\d+)", line)
            if m:
               word, rel, wirt, occ = m.groups()
               occ = int(occ)
               occ_list.append(occ)
               observed[word, rel, wirt].append(occ / 1064542.0)
        
        pprint(occ_list)
        pprint(dict(observed))
        

        Output

        [1, 1, 6, 1, 1, 1, 1]
        {('abroad', 'a:at:n', 'request'): [9.393711098293914e-07],
         ('abroad', 'a:at:n', 'silence'): [9.393711098293914e-07],
         ('abroad', 'a:at:n', 'time'): [5.636226658976349e-06],
         ('abroad', 'a:because of:n', 'schedule'): [9.393711098293914e-07],
         ('abroad', 'a:by:n', 'american'): [9.393711098293914e-07],
         ('abroad', 'a:by:n', 'bank'): [9.393711098293914e-07],
         ('abroad', 'a:by:n', 'blow'): [9.393711098293914e-07]}
        

        【讨论】:

        • 谢谢!这几乎就是我想要的。我之前曾尝试使用 re ,但放弃了;我猜我执行不正确。我改用以下内容,因为它对我来说更清晰一些,并且还捕获了“wirt”部分中的多词短语: m = re.search(r"(\S+)\s(\S:\w+\s *\S*:\S+)\s(\S+\s*\S*\s*\S*)\s(\d+)", 行)
        【解决方案4】:

        这是一个仅使用 splitrsplit 的版本:

        for line in lines:
            word, s = line.strip().split(' ', 1)
            s, occ = s.rsplit(' ', 1)
            rel, s = s.rsplit(':', 1)
            s, wirt = s.split(' ', 1)       
            arb = (word, rel + ':' + s, wirt)
            occ_list.append(int(occ))
        

        【讨论】:

          猜你喜欢
          • 2010-11-12
          • 2021-05-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-29
          • 2023-01-28
          • 2023-03-14
          相关资源
          最近更新 更多