【问题标题】:Create a dictionary with multiple value创建具有多个值的字典
【发布时间】:2021-12-04 04:47:32
【问题描述】:

我有一个包含 mac_addressRSSI 值和 time 值的文件;我想创建一个字典,其中键是 mac_address,值是 RSSItime

我该怎么做?

文件格式如下:

6E:C6:F8:89:AE:64   -71dBm  10:18:25
C4:A5:DF:24:05:7E   -45dBm  10:18:26
B0:6E:BF:1F:5E:A1   -27dBm  10:18:48

但有时我可以有超过 3 行。

【问题讨论】:

    标签: python file dictionary


    【解决方案1】:

    您可以使用字典理解:

    with open('file.txt') as f:
        mac_dic = {k:tuple(v) for k,*v in map(str.split, f)}
    

    输出:

    >>> mac_dic
    {'6E:C6:F8:89:AE:64': ('-71dBm', '10:18:25'),
     'C4:A5:DF:24:05:7E': ('-45dBm', '10:18:26'),
     'B0:6E:BF:1F:5E:A1': ('-27dBm', '10:18:48')}
    

    这是另一种格式:

    with open('file.txt') as f:
        mac_dic = {k:dict(zip(['RSSI', 'time'], v))
                   for k,*v in map(str.split, f)}
    
    >>> mac_dic
    {'6E:C6:F8:89:AE:64': {'RSSI': '-71dBm', 'time': '10:18:25'},
     'C4:A5:DF:24:05:7E': {'RSSI': '-45dBm', 'time': '10:18:26'},
     'B0:6E:BF:1F:5E:A1': {'RSSI': '-27dBm', 'time': '10:18:48'}}
    

    【讨论】:

      【解决方案2】:

      使用类型提示和 NamedTuple

      from typing import NamedTuple,Dict
      
      class RSSI(NamedTuple):
        rssi: str
        time:str
      
      mac = str
      
      data: Dict[mac,RSSI] = dict()  
      with open('test.txt') as f:
        for line in f:
          mac,rssi,time = line.split()
          data[mac] = RSSI(rssi,time)
      print(data)
      

      输出

      {'6E:C6:F8:89:AE:64': RSSI(rssi='-71dBm', time='10:18:25'), 'C4:A5:DF:24:05:7E': RSSI(rssi='-45dBm', time='10:18:26'), 'B0:6E:BF:1F:5E:A1': RSSI(rssi='-27dBm', time='10:18:48')}
      

      【讨论】:

        【解决方案3】:

        如果@mozway 的答案对你来说有点太复杂,也许我的答案会让你更容易理解!

        解决方案 1:列表/元组

        您可以将 MAC 地址用作键,并将包含 RSSI 和时间的列表/元组作为值:

        mydict = {
            '6E:C6:F8:89:AE:64': [-71, '10:18:25'],
            'C4:A5:DF:24:05:7E': [-45, '10:18:26'],
            'B0:6E:BF:1F:5E:A1': [-27, '10:18:48'],
        }
        
        # example: accessing the rssi of '6E:C6:F8:89:AE:64'
        print(mydict['6E:C6:F8:89:AE:64'][0])  # -71
        

        解决方案 2:字典

        或以字典作为外部字典值的嵌套字典结构:

        mydict = {
            '6E:C6:F8:89:AE:64': {'rssi': -71, 'time': '10:18:25'},
            'C4:A5:DF:24:05:7E': {'rssi': -45, 'time': '10:18:26'},
            'B0:6E:BF:1F:5E:A1': {'rssi': -27, 'time': '10:18:48'},
        }
        
        # example: accessing the rssi of '6E:C6:F8:89:AE:64'
        print(mydict['6E:C6:F8:89:AE:64']['rssi'])  # -71
        

        【讨论】:

          【解决方案4】:
          with open("file.txt","w") as f:
              f.write("""6E:C6:F8:89:AE:64  -71dBm   10:18:25
          C4:A5:DF:24:05:7E  -45dBm   10:18:26
          B0:6E:BF:1F:5E:A1  -27dBm   10:18:48""")
          
          dic = {}
          data = []
          with open("file.txt","r") as f:
          
              data = f.read().split("\n")
          for i in range(len(data)) :
              string = data[i].split(" ")
              for i in range(string.count("")):
                  string.remove("")
                  dic[string[0]] = " ".join(string[1:])
              print(dic)
          

          【讨论】:

          • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
          【解决方案5】:

          您可以申请DictReader 来处理此文件。目前尚不清楚列之间有什么分隔符,它可能是\t 或多个空格。对于多个空格分隔符,您需要设置skipinitialspace

          代码:

          from csv import DictReader
          
          with open(r"path/to/file") as f:
              # setup if delimiter is "\t"
              reader = DictReader(f, ("mac_address", "rssi", "time"),
                                  delimiter="\t")
              # setup if delimiter is spaces
              reader = DictReader(f, ("mac_address", "rssi", "time"),
                                  delimiter=" ", skipinitialspace=True)
              result = {}
              for row in reader:
                  result[row.pop("mac_address")] = row
              # Or you can use one-liner
              result = {row.pop("mac_address"): row for row in reader}
          

          结果:

          {
              '6E:C6:F8:89:AE:64': {
                  'rssi': '-71dBm',
                  'time': '10:18:25'
              },
              'C4:A5:DF:24:05:7E': {
                  'rssi': '-45dBm',
                  'time': '10:18:26'
              },
              'B0:6E:BF:1F:5E:A1': {
                  'rssi': '-27dBm',
                  'time': '10:18:48'
              }
          }
          

          你还添加了下一个:

          但有时我可以有超过 3 行

          您可以将所有可能的列传递给DictReader 构造函数,并使用restval 参数设置默认值。


          更新。原始文件有标签作为列之间的分隔符(Symon94's comment),所以最终代码是:

          from csv import DictReader
          
          with open(r"path/to/file") as f:
              reader = DictReader(f, ("mac_address", "rssi", "time"), delimiter="\t")
              result = {row.pop("mac_address"): row for row in reader}
          

          【讨论】:

          • 感谢您的解决方案,我在 mac_address、RSSI 值和时间值之间使用制表符来显示空格
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-03-01
          • 1970-01-01
          • 2012-10-30
          • 2021-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多