仅使用一个for循环从列表列表创建字典

时间:2020-07-03 13:02:14

标签: python-3.x list dictionary for-loop nested-lists

我在测试中遇到了这个问题。这个问题有两个部分:

第一部分:

给出风味列表,例如。 ['A','A','A','A','B','B','B','B','B','C','C','C',' C'],编写一个函数,分别返回每种口味编号的字典。

我的解决方案:

flavors = ['A','A','A','A','B','B','B','B','B','C','C','C','C']

def count_flavors(l):
    dict_flavors={}
    for i in l:
        dict_flavors[i] = l.count(i)
    return dict_flavors

print(count_flavors(flavors))

第二部分:

使用不超过一个的循环编写一个函数,该函数接受风味列表的列表,例如。 [['A','A','B','B','B','C','C'],['A','A','B','B','B ','B','C'],['A','B','C','C']],并返回每种口味总数的字典。您必须在此解决方案中包括您在第一部分中定义的功能。 (为澄清起见,基本上只应该有两个for循环;一个来自第一部分,一个来自第二部分)

到目前为止,我的解决方法是:

batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']]

def batch_count(b):
    batch_dict = []
    result = {}
    for j in b:
        batch_dict.append(count_flavors(j))
    print(batch_dict)
    for i in batch_dict:
        for k in i.keys():
            result[k] = result.get(k,0) + i[k]
    return result

print('batch count 1:' + str(batch_count(batches)))

我正在努力寻找一种解决方案,该部分仅使用一个for循环。我知道有一些类似collections.Counter()这样的模块。天真的解决方案可能不包含任何模块来解决此问题?

谢谢!

2 个答案:

答案 0 :(得分:2)

这是最幼稚的解决方案,我可以想到,以实现您想要的

使用该解决方案的好处

  1. 不需要创建额外的变量,例如int diff = a-b; while (diff >= 3) { a -= b; diff = a-b; } ,这会占用系统中不必要的空间
  2. 像上面使用batch_dict = []一样,无需使用不同的方法进行多次计算
  3. 直率且易于理解

最终解决方案

count_flavors()

也可以在其他一些批次中对此进行测试,并告诉我。到目前为止,这是天真的解决方案,可以给出您想要实现的目标。继续学习:)

另一种解决方案[使用第一种方法COUNT_FLAVORS]

嘿,如果您真的想使用第一种方法,那么可以解决,但是现在您需要妥协一件事,即必须导入batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']] def batch_count(b): result = {} # for storing final count results # two loops are required to get into the arrays of array, not other option is there for items in b: # Getting the nested array item here for item in items: # final computation, if the item is there in the result dict, then increment # else simply assign 1 to the item as a key which eventually gives you the total number # of counts of each item throughout the batches array items if item in result: result[item] += 1 else: result[item] = 1 return result print('batch count 1:' + str(batch_count(batches))) # OUTPUT # >>> batch count 1:{'A': 7, 'C': 7, 'B': 10} ,但是我向您保证,就这么简单,并会给您直接答案

您的Counter工作正常,因此我们按原样使用count_flavors。 我们现在将更改count_falvors()方法

最终解决方案

batch_count

通过这种方式,您也可以使用from collections import Counter # Taking your method as is, to get the dictionary which counts # the items occurence from your array def count_flavors(l): dict_flavors={} for i in l: dict_flavors[i] = l.count(i) return dict_flavors # This method will do your stuffs def batch_count(b): result = {} #this will be used to return the final result # now just one loop, since we will passing the array # to our method for computation count_flavors() for items in b: # this will give out single array ''' now we will call your count_flavor method we will use Counter() to merge the dictionary data coming from the count_flavor and then add it to the result Counter() keep track of same item, if present in multiple dict, ADDS +1 to the same item, doesn't duplicate value Hence counter required ''' if len(result) != 0: # if the result is not empty, then result = result + data result += Counter(count_flavors(items)) # no more extra for loop else: # else first fill the data by assigning it result = Counter(count_flavors(items)) # this will give out the output in {} # else the output will come in Counter({}) format return dict(result) # our test array of arrays batches = [['A','A','A','A','B','B','B','B','B','C','C','C','C'], ['A', 'A', 'B', 'B' ,'B','B','C'], ['A','B','C','C']] print('batch count 1:' + str(batch_count(batches))) # OUTPUT # >>> batch count 1:{'A': 7, 'B': 10, 'C': 7} 方法获得输出,而count_flavors()中也没有多个循环。希望可以使您更加清楚:)。如果这对您有用,那么您可以接受答案,对于将要寻找此问题答案的人们而言:)

答案 1 :(得分:1)

通过以这种方式修改方法,第一个功能可以变得更快:

def count_flavors(lst):
    dict_flavors = {}
    for item in lst:
        if item in dict_flavors:
            dict_flavors[item] += 1
        else:
            dict_flavors[item] = 1
    return dict_flavors

您还可以使用Counter来简化代码:

from collections import Counter

def count_flavors(lst):
    return dict(Counter(lst))

第二个函数可以使用itertools.chain

from collections import Counter
from itertools import chain

def batch_count(b):
    return dict(Counter(chain(*b)))