列表理解嵌套在字典理解中

List Comprehension nested in Dict Comprehension

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

输出会是这样的:

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

关于过滤 list/values 而不是创建它们的类似问题。

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

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) 

你可以写第二个循环这样你只需要写一次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]}

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

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

您实际上不需要执行所有这些强力除法。每第三个数可被三整除,每七个数可被七整除,依此类推:

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