列表理解嵌套在字典理解中
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)}
我想创建一个以列表作为值的字典,列表中的内容取决于键(数字 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)}