搜索Python字典并在找到的地方增加值

2024-09-28 03:23:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python数据字典:

    [
    {u'PhoneOwner': u'Bob', u'Frequency': 0, u'PhoneNumber': u'123456789'},
    {u'PhoneOwner': u'Sarah', u'Frequency': 0, u'PhoneNumber': u'98765431'}
    ]

我有一个使用PhoneNumber的通话列表,我想尝试将列表与字典进行比较,并在我列表中的号码出现在字典中时更新频率,最终得到:

    [
    {u'PhoneOwner': u'Bob', u'Frequency': 5, u'PhoneNumber': u'123456789'},
    {u'PhoneOwner': u'Sarah', u'Frequency': 8, u'PhoneNumber': u'98765431'}
    ]

目前我有:

      with open("CallLog.txt") as connectedNumbers:         
      for line in connectedNumbers:
      try:
              phoneNumberDictionary[PhoneNumber] += phoneNumberDictionary[Frequency]1
      except KeyError:
              phoneNumberDictionary[PhoneNumber] = phoneNumberDictionary[Frequency]1

我找不到有关如何搜索词典的一个字段并在找到匹配项时更新另一个字段的任何详细信息。 我哪里出错了?你知道吗


Tags: 数据列表字典withopen号码频率bob
3条回答

您不能搜索字典的值:它是由它的键索引的,而值根本没有索引(事实上,它们甚至可能是不可散列的)。你知道吗

然后有两个选项:

  1. 重新设计问题,使电话号码实际上是关键:

    {
         u'123456789': {u'PhoneOwner': u'Bob', u'Frequency': 0},
         u'98765431': {u'PhoneOwner': u'Sarah', u'Frequency': 0},
    }
    

    这非常实用,因为它可以让您立即索引词典:

    with open("Calllog.txt") as log:
        for line in log:
            phoneNumberDictionary[line]['Frequency'] += 1
    

    但这意味着您将不得不重做数据,可能工作量很大,而且这可能不是处理数据的最方便的方法(例如,按所有者名称搜索)

  2. 将数据结构保留为列表,并直接在其中搜索匹配项:

    with open("Calllog.txt") as log:
        for line in log:
            entries = filter(lambda entry: entry['PhoneNumber'] == line, phoneNumberDirectory)
            for entry in entries:
                entry['Frequency'] += 1
    

    这将很好地工作(让几个人有相同的电话号码。好的,坏的?这由您自己决定),但每次遍历整个目录时显然效率很低。如果您有一个已知的小数据集,这可能是最好的解决方案。

  3. (在我看来,最好的选择)两者的某种结合。通常可以将数据存储在对象中,并将多个索引作为字典:

    class PhoneNumbers(object):
        def __init__(self, entries):
            self.frequencies = []
            self.names = {}
            self.numbers = {}
            for i, entry in enumerate(entries):
                self.frequencies.append(entry['Frequency'])
                self.names[entry['PhoneOwner']] = entry['PhoneNumber']
                self.numbers[entry['PhoneNumber']] = i
    
        def register_call(self, number):
            self.frequencies[self.numbers[number]] += 1
    
    data = PhoneNumbers(phoneNumberDictionary)
    with open("Calllog.txt") as log:
        for line in log:
            data.register_call(line)
    

    或者这些行周围的一些变化与您打算对数据执行的操作相匹配。

看,你有一个字典列表,你必须遍历这个列表并检查这行是否与特定字典的PhoneNumber匹配。如果匹配,则将字典的Frequency增加1。你知道吗

  with open("CallLog.txt") as connectedNumbers:         
  for line in connectedNumbers:
      for value in data:
          if line== value['PhoneNumber']:
              value['Frequency']+=1

我要提个建议:

把phoneNumberDict变成一本词典。每个键将是一个电话号码,每个值将是一个dict与其余的信息。这样,您就不必每次都循环查看字典列表。你知道吗

观察:

phoneNumberDictionary = { 
                         '123456789': {u'PhoneOwner': u'Bob', u'Frequency': 0},
                         '987654321': {u'PhoneOwner': u'Sarah', u'Frequency': 0}
                        }
callLogList = ['123456789', 
               '123456789', 
               '123456789', 
               '123456789', 
               '123456789', 
               '987654321', 
               '987654321', 
               '987654321', 
               '987654321', 
               '987654321', 
               '987654321', 
               '987654321', 
               '987654321',
               '000000000'
              ]

for phoneNumber in callLogList:
    if phoneNumber in phoneNumberDictionary:
        phoneNumberDictionary[phoneNumber]['Frequency'] += 1

print (phoneNumberDictionary)

无需每次循环查看电话号码列表,这将是一个更高效的脚本,尤其是随着电话号码列表的增长。你知道吗

我还将for循环的try-except改为if语句,因为这比每次不包含数字时捕获异常要快。我已经包括一个无用的电话号码,所以你可以看到它仍然正常工作。你知道吗

希望这有帮助。你知道吗

相关问题 更多 >

    热门问题