繁体   English   中英

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

[英]Search Python Dictionary and increment value where found

我在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

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

您无法搜索字典的值:字典是由其键索引的,而值根本没有索引(实际上,它们甚至可能不可散列)。

然后,您有两个选择:

  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) 

    或围绕这些线的一些变化与您打算对数据进行的匹配。

我将提出一个建议:

将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语句,因为它比每次不包含数字时捕获异常都要快。 我提供了一个无效的电话号码,因此您可以看到它仍然可以正常使用。

希望这可以帮助。

如果现在更改数据结构还为时不晚,那么从电话列表转换为以电话号码为键的顶级命令的命令效率会更高。 如果由于顺序很重要而使用列表,则可以使用OrderedDict

要使用当前的数据结构来回答您的问题:由于您有一个字典列表,因此您要做的第一件事就是找到与您要增加的电话号码相对应的字典。 您可以使用下面的类似index_dict_in_list()的函数来执行此操作:

def index_dict_in_list(list_, key, value):
    """
    Given a list of dicts, a key, and a value, return the
    index of the dict with the matching key:value pair.
    """
    for idx, dict_ in enumerate(list_):
        if dict_[key] == value:
            return idx
    return -1

然后,您可以像这样使用它:

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

page = index_dict_in_list(phonebook, 'PhoneNumber', '98765431')
phonebook[page]['Frequency'] =+ 1

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM