0

I want to create a dict with lists as values, where the content on the lists depends on whether or not the key (numbers 1 to 100) is dividable by 3,5 and/or 7

The output would be like this:

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

Similar questions where about filtering the list/values, not creating them.

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 

This works just fine, but is there a way to do this with a pythonic one-/twoliner?

Something along like this: d = dict((val, range(int(val), int(val) + 2)) for val in ['1', '2', '3'])

0

4 Answers 4

1

Pythonic is not about one or two liners. In my opinion is (mainly) about readability, perhaps this could be considered more 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) 
Sign up to request clarification or add additional context in comments.

Comments

1

You don't actually need to do all these brute-force divisions. Every third number is divisible by three, every seventh number is divisible by seven, etc:

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 

So the best approach should take advantage of that fact, using the repeating patterns of modulo. Then, we can just zip the range with however many iterators you want to use.

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

Comments

0

There is actually a one liner that isnt even that complicated :)

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

3 Comments

however how would you do it if it HAD to be different values, so not just div/nodiv but div3/nodiv3 and so on?
you could use some mor else/if statements for that purpose i guess, but at some point its getting ugly.. stackoverflow.com/a/9987533/11951277
My approach is about 400% more efficient than this answer, according to timeit.
0

you could write a second loop so that you only have to write if...else only once

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 

or

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.