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

Creating a dictionary from list of lists using only one for loop

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

第一部分:

给定一个口味列表,例如。 ['A','A','A','A','B','B','B','B','B','C','C','C','C'],写一个函数,returns一个字典,分别表示每种口味的个数

我的解决方案:

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))

第二部分:

使用不超过一个的 for 循环编写一个函数,该函数接受一列口味列表,例如。 [['A', 'A', 'B', 'B', 'B', 'C', 'C'], ['A', 'A', 'B', 'B', 'B', 'B', 'C'], ['A', 'B', 'C', 'C']] 和 returns 每种口味总数的字典。您必须在此解决方案中包含您在第一部分中定义的函数。 (澄清一下,基本上应该只有两个 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() 之类的东西。是否有一个不包含任何模块的简单解决方案可以解决这个问题?

谢谢!

这是最好的天真解决方案我能想到的为了实现你想要的

使用该解决方案的好处

  1. No need to create extra variable like batch_dict = [], which takes unnecessary space in your system
  2. No need to carry out multiple computations using different methods, like you did above using count_flavors()
  3. Straight forward and easy to understand

最终解决方案

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}

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

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

嘿,如果你真的想使用第一种方法,那么有一个解决方法,但你现在需要妥协一件事,那就是 Counter 必须导入,但我向你保证, 就这么简单, 直接给你答案

Your count_flavors works fine, so we take the count_falvors() as is. We will be making changes to the batch_count method now

最终解决方案

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() 方法实现输出,batch_count() 中也没有多个循环。希望这会让你更清楚 :)。如果这对你有效,你可以接受这个答案,因为那些会来寻找这个问题答案的人:)

通过以这种方式修改您的方法,第一个函数可以变得更快:

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)))