【问题标题】:Matching one set of values to another in a text file将一组值与文本文件中的另一组值匹配
【发布时间】:2012-11-17 04:11:09
【问题描述】:

我有一个包含以下信息的文本文件:

1961 - Roger (Male)
1962 - Roger (Male)
1963 - Roger (Male)
1963 - Jessica (Female)
1964 - Jessica (Female)
1965 - Jessica (Female)
1966 - Jessica (Female)

如果我想在文件中搜索单词“Roger”,我希望它打印出该名称对应的年份,即 1961、1962、1963。最好的方法是什么?

我是用字典做的,但后来意识到字典不能有重复的值,并且 1963 在文本文件中被提到了两次,所以它不起作用。

我正在使用 Python 3,谢谢。

【问题讨论】:

  • 使用collections.defaultdict(list),其中键是姓名(可能是+性别),并且年份附加到相应的值,该值将自动以空列表开始。

标签: python list python-3.x


【解决方案1】:

使用以名称为键的字典,并将年份存储在列表中:

In [1]: with open("data1.txt") as f:
   ...:     dic={}
   ...:     for line in f:
   ...:         spl=line.split()
   ...:         dic.setdefault(spl[2],[]).append(int(spl[0]))
   ...:     for name in dic :    
   ...:         print (name,dic[name])
   ...:       

Roger [1961, 1962, 1963]
Jessica [1963, 1964, 1965, 1966]

或者你也可以使用collections.defaultdict:

In [2]: from collections import defaultdict

In [3]: with open("data1.txt") as f:
   ...:     dic=defaultdict(list)
   ...:     for line in f:
   ...:         
   ...:         spl=line.split()
   ...:         dic[spl[2]].append(int(spl[0]))
   ...:     for name in dic:    
   ...:         print name,dic[name]
   ...:         
Roger [1961, 1962, 1963]
Jessica [1963, 1964, 1965, 1966]

【讨论】:

  • 你再次对 Ashwini 有很大帮助。但是,它可以工作,但是,我拥有的实际文件中的某些名称具有中间名,因此 spl[2] 并非一直都有效。我做了 line.split('-') 来解决这个问题,但它总是在每行的末尾产生一个“\n”,知道为什么吗?
  • @Goose 您可以使用strip() 或简单地使用line.strip('\n').split('-') 来阅读\n
【解决方案2】:

为什么您不能使用字典和名称索引(例如Roger)作为键并将值作为年份列表(此处为[1961,1962,1963]?这对您不起作用吗?

所以在循环结束时,您会得到所有名称与年份一致的值,这正是您想要的。

【讨论】:

  • 我尝试使用 dict 方法,所以我将键作为年份,将值作为名称,当我在 dict 中搜索匹配“Roger”的值时,它得到了 1961、1962 但不是 1963因为杰西卡也分享了那一年。
  • 将“roger”作为键,将“years”作为值。那么就可以了。
【解决方案3】:

使用tuples。它们可以存储在列表中,并可以迭代。

假设您的列表如下所示:

data = [(1961, 'Rodger', 'Male'),
        (1962, 'Rodger', 'Male'),
        (1963, 'Rodger', 'Male'),
        (1963, 'Jessica', 'Female')]

您可以像这样对其运行查询:

# Just items where the name is Rodger
[(y, n, s) for y, n, s in data if n == "Rodger"]

# Just the year 1963
[(y, n, s) for y, n, s in data if y == 1963]

或者使用更多 Pythonic 代码:

for year, name, sex in data:
    if year >= 1962:
        print "In {}, {} was {}".format(year, name, sex)

1962 年,罗杰是男性
1963 年,罗杰是男性
1963年,杰西卡是女性

【讨论】:

    【解决方案4】:

    您始终可以使用正则表达式。

    import re
    
    f = open('names.txt')
    name = 'Roger'
    
    for line in f.readlines():
        match = re.search(r'([0-9]+) - %s' % name, line)
        if match:
            print match.group(1)
    

    【讨论】:

      【解决方案5】:

      正如我在 cmets 中建议的那样:

      from collections import defaultdict
      
      result = defaultdict(list)
      with open('data.txt', 'rt') as input:
          for line in input:
              year, person = [item.strip() for item in line.split('-')]
              result[person].append(year)
      
      for person, years in result.items():
          print(person, years, sep=': ')
      

      输出:

      Roger (Male): ['1961', '1962', '1963']
      Jessica (Female): ['1963', '1964', '1965', '1966']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-20
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多