【问题标题】:Adding list in form of tuples to a dictionary将元组形式的列表添加到字典
【发布时间】:2023-04-02 22:25:01
【问题描述】:

假设有一个包含这样子列表的列表

[[2013, 'Patric', 'M', 1356], [2013, 'Helena', 'F', 202], [2013, 'Patric', 'F', 6],[1993, 'Patric', 'F', 7]......]

这是def list_of_names() 的输出,其中 2013 年是年份,M 是性别,1356 是 M 出生人数等。

我想创建一个字典,将名称作为键输出,将值作为元组 (year, number_of_males,number_of_females) 输出。比如:

{ .. ’Patric’:[... , (1993, 0, 7), (2013, 1356, 6), ... ], ... }.

技术上1993年是年,0是男性的数量,7是女性的数量,元组应该按照年份的顺序排列。

我不知道如何将此信息添加到字典中

def name_Index(names):
    d = dict()
    L = readNames() #the list with from previous def which outputs different names and info as above
    newlist = []
    for sublist in L:

【问题讨论】:

    标签: python list dictionary tuples


    【解决方案1】:
    from collections import defaultdict
    
    def list_of_names():
        return [[2013, 'Patric', 'M', 1356],
                [2013, 'Helena', 'F', 202],
                [2013, 'Patric', 'F', 6],
                [1993, 'Patric', 'F', 7]]
    
    def name_Index():
        tmp = defaultdict(lambda:defaultdict(lambda: [0,0]))
    
        for year, name, sex, N in list_of_names():
            i = 0 if sex == 'M' else 1
            tmp[name][year][i] += N
    
        d = {}
        for name, entries in tmp.items():
            d[name] = [(year, M, F) for (year, (M,F)) in entries.items()]
    
        return d
    
    print name_Index()
    

    【讨论】:

      【解决方案2】:

      这是我对这个问题的尝试:

      from collections import defaultdict, namedtuple
      from itertools import groupby
      
      data = [[2013, 'Patric', 'M', 1356],
              [2013, 'Helena', 'F', 202],
              [2013, 'Patric', 'F', 6],
              [1993, 'Patric', 'F', 7]]
      
      names = defaultdict(list)
      datum = namedtuple('datum', 'year gender number')
      for k, g in groupby(data, key=lambda x: x[1]):
          for l in g:
              year, name, gender, number = l
              names[k].append(datum(year, gender, number))
      
      final_dict = defaultdict(list)
      for n in names:
          for k, g in groupby(names[n], lambda x: x.year):
              males = 0
              females = 0
              for l in g:
                  if l.gender == 'M':
                      males += l.number
                  elif l.gender == 'F':
                      females += l.number
              final_dict[n].append((k, males, females))
      
      print(final_dict)
      

      【讨论】:

      • 伙计,再次使用itertools 感觉很好。我还是明白了:)
      【解决方案3】:

      最方便的是使用collections.defauldict。它返回类似字典的对象,如果找不到键,则返回默认值。在您的情况下,您使用 list 作为默认值,并在循环中将元组附加到它:

      from collections import defaultdict
      
      names = [ [2013, 'Patric', 'M', 1356], 
              [2013, 'Helena', 'F', 202], 
              [2013, 'Patric', 'F', 6],
              [1993, 'Patric', 'F', 7]    ]
      
      def name_Index(data):
          # name => year => sex
          d = defaultdict(lambda: defaultdict(lambda: {'F': 0, 'M': 0})) 
          for year, name, sex, births in data:
              d[name][year][sex] += births
      
          # if you are fine with defauldict result: return d
          # else collect results into tuples:
      
          result = {}
          for name, data in d.items():
              result[name] = [(year, c['M'], c['F']) for year, c in data.items()]
          return result
      
          print name_Index(names)
          # {'Helena': [(2013, 0, 202)], 'Patric': [(1993, 0, 7), (2013, 1356, 6)]}
      

      【讨论】:

      • 假设您的 readNameslst 返回/产生项目,但这(还)不在代码 sn-p 中。
      • 不错。存根添加
      • 这不会返回他正在寻找的内容。
      • 很抱歉不清楚。但是代码应该做的是获取一个包含 500 个或更多子列表的列表并创建一个字典。但有不同的标准。例如,从上面的列表 (lst) Patric 是键,值应该是 [(1993, 0, 7), (2013, 1356, 202)..] 所以元组应该从同一个中获取男性和女性的数量year(年、男数、女数),如果没有男数据则为零。
      • 是的,我误解了 OP 到底想要什么。现在应该没问题了。
      【解决方案4】:

      我不明白您为什么将名称作为 name_Index 函数的参数然后调用 readNames,您的工作必须有一些必要性。因此,我只是放置了一个虚拟的 readNames 函数并将 None 作为参数发送给 name_Index。使用类是解决复杂数据结构的好方法。顺便说一句,我必须承认写得很好的问题。

      def readNames ():
          return [[2013, 'Patric', 'M', 1356], [2013, 'Helena', 'F', 202], [2013, 'Patric', 'F', 6],[1993, 'Patric', 'F', 7]]
      
      class YearOb(object):
          def __init__(self): 
              self.male = 0
              self.female = 0
      
          def add_birth_data(self, gender, birth_count):
              if gender == "M":
                  self.male += birth_count
              else:
                  self.female += birth_count
      
      class NameOb(object):
          def __init__(self):
              self.yearobs = dict()
      
          def add_record(self, year, gender, birth_count):
              if year not in self.yearobs:
                  self.yearobs[year]=YearOb()
      
              self.yearobs[year].add_birth_data(gender, birth_count)           
      
          def get_as_list(self):
              list_data = []
              for year, yearob in self.yearobs.items():
                  list_data.append((year, yearob.male, yearob.female))
              return list_data
      
      def name_Index(names):
          d = dict()
          L = readNames() #the list with from previous def which outputs different names and info as above
          newlist = []
          for sublist in L:
              name = sublist[1]
              if name not in d:
                  d[name]=NameOb()
              d[name].add_record(sublist[0], sublist[2], sublist[3])
      
          for name, nameob in d.items():
              d[name] = nameob.get_as_list() 
      
          return d 
      
      
      print(name_Index(None))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-31
        • 2011-04-29
        • 2020-09-08
        • 2018-08-27
        • 1970-01-01
        相关资源
        最近更新 更多