【问题标题】:List Comprehension nested in Dict Comprehension嵌套在字典理解中的列表理解
【发布时间】:2021-02-23 15:51:49
【问题描述】:

我想创建一个以列表为值的字典,其中列表上的内容取决于键(数字 1 到 100)是否可被 3,5 和/或 7 整除

输出会是这样的:

{
    1: ['nodiv3', 'nodiv5', 'nodiv7'],
    3: ['div3', 'nodiv5', 'nodiv7'],
    15: ['div3', 'div5', 'nodiv7'],
}

关于过滤列表/值而不是创建它们的类似问题。

dict_divider = {}
for x in range(0,101):
    div_list= []
    if x % 3 == 0:
        div_list.append('div3')
    else:
        div_list.append('nodiv3')
    if x % 5 == 0:
        div_list.append('div5')
    else:
        div_list.append('nodiv5')
    if x % 7 == 0:
        div_list.append('div7')
    else:
        div_list.append('nodiv7')
    dict_divider[x] = div_list

这很好用,但是有没有办法使用 pythonic one-/twoliner 做到这一点?

类似这样的东西:d = dict((val, range(int(val), int(val) + 2)) for val in ['1', '2', '3'])

【问题讨论】:

    标签: python list-comprehension dictionary-comprehension


    【解决方案1】:

    Pythonic 不是关于一两个班轮。在我看来(主要)是关于可读性,也许这可以被认为更pythonic

    def label(n, divisor):
        return f"{'' if n % divisor == 0 else 'no'}div{divisor}"
    
    
    def find_divisors(n, divisors=[3, 5, 7]):
        return [label(n, divisor) for divisor in divisors]
    
    
    dict_divider = {x: find_divisors(x) for x in range(1, 101)}
    
    print(dict_divider) 
    

    【讨论】:

      【解决方案2】:

      您实际上并不需要进行所有这些蛮力划分。每第三个数字可以被三整除,每七个数字可以被七整除,等等:

      0 1 2 3 4 5 6 7 8 9 ...  <-- range(10)
      0 1 2 0 1 2 0 1 2 0 ...  <-- mod 3
      
      0 1 2 3 4 5 6 7 8 9 ...  <-- range(10)
      0 1 2 3 4 5 6 0 1 2 ...  <-- mod 7
      

      所以最好的方法应该利用这个事实,使用模数的重复模式。然后,我们可以使用您想使用的任意数量的迭代器来压缩范围。

      import itertools
      
      def divs(n):
          L = [f"div{n}"] + [f"nodiv{n}"] * (n - 1)
          return itertools.cycle(L)
      
      repeaters = [divs(n) for n in (3, 5, 7)]
      d = {x: s for x, *s in zip(range(101), *repeaters)}
      

      【讨论】:

        【解决方案3】:

        实际上有一个甚至没有那么复杂的班轮:)

        my_dict = {}
        for i in range(100):
            my_dict[i] = ['div' + str(n) if i % n == 0 else 'nodiv' + str(n) for n in [3,5,7]]
        

        【讨论】:

        • 但是,如果它必须是不同的值,你会怎么做呢?不仅是 div/nodiv,还有 div3/nodiv3 等等?
        • 我猜你可以使用一些 mor else/if 语句来达到这个目的,但在某些时候它会变得丑陋..stackoverflow.com/a/9987533/11951277
        • 根据timeit,我的方法比这个答案的效率大约高 400%。
        【解决方案4】:

        您可以编写第二个循环,这样您只需编写一次if...else

        dict_divider = {}
        div_check_lst = [3, 5, 7]
        for x in range(0,101):
            div_list= []
            for div_check in div_check_lst:
                if x % div_check == 0:
                    div_list.append(f'div{str(div_check)}')
                else:
                    div_list.append(f'nodiv{str(div_check)}')
            dict_divider[x] = div_list
        

        dict_divider = {x:[f'{'no' * x % div_check != 0}div{str(div_check)}' for x in range(0,101) for div_check in div_check_lst]}
        

        【讨论】:

          猜你喜欢
          • 2013-11-15
          • 1970-01-01
          • 2021-12-22
          • 1970-01-01
          • 2020-01-08
          • 2017-11-27
          • 2018-08-23
          • 2019-10-23
          • 1970-01-01
          相关资源
          最近更新 更多