Python Forum
Giving all possible values to four different variables
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Giving all possible values to four different variables
#1
I have for different values which are a b c d. Their sum should be always 1
And they can take 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 but the sum always should be 1. and they can take same values too.
I want to print all possible combinations for these 4 variables like that:

a, b, c, d = 0.5, 0.2, 0.2, 0.1
a, b, c, d = 1.0, 0.0, 0.0, 0.0
a, b, c, d = 0.5, 0.0, 0.4, 0.1
.
.
.
How can I do that in simplest way?
Reply
#2
The most obvious way (and ugliest, I guess):
>>> for a in range(11):
...     for b in range(11):
...         for c in range(11):
...             for d in range(11):
...                 if a+b+c+d == 10:
...                     print(a/10, b/10, c/10, d/10)
Reply
#3
(Jan-17-2021, 09:45 PM)Serafim Wrote: The most obvious way (and ugliest, I guess):
>>> for a in range(11):
...     for b in range(11):
...         for c in range(11):
...             for d in range(11):
...                 if a+b+c+d == 10:
...                     print(a/10, b/10, c/10, d/10)

Thank you very much but I really do not want to use 4 for loop Because it is a part of a very long code and 4 for loop will make it code much more longer
Reply
#4
Yeah, this is small enough that there's only 11^4, or less than 15000. So brute-force is fine. You could instead brute-force through the first 3, then pick the 4th that matches.

from itertools import product

items = [x/10 for x in range(11)]

matching_sets = (x for x in product(items, repeat=4) if 0.99 < sum(x) < 1.01)
for answer in matching_sets:
    print(f"a, b, c, d = {', '.join(str(x) for x in answer)}")
Serafim likes this post
Reply
#5
(Jan-17-2021, 09:54 PM)bowlofred Wrote: Yeah, this is small enough that there's only 11^4, or less than 15000. So brute-force is fine. You could instead brute-force through the first 3, then pick the 4th that matches.

from itertools import product

items = [x/10 for x in range(11)]

matching_sets = (x for x in product(items, repeat=4) if 0.99 < sum(x) < 1.01)
for answer in matching_sets:
    print(f"a, b, c, d = {', '.join(str(x) for x in answer)}")

I now wrote this code:

import itertools
for four in itertools.product([0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9, 1.0], repeat=4): 
    a,b,c,d = four[0],four[1],four[2],four[3]
    if a+b+c+d ==1:
        print (a,b,c,d)
Which one is better/efficient?
Reply
#6
Beware floating point math. Many decimals cannot be represented exactly. Either check for approximate solutions, or do your math with integers and then divide by 10 later. Otherwise you will run into problems.

>>> 0.3 + 0.3 + 0.3 + 0.1 == 1.0
False
Workaround 1
>>> 3 + 3 + 3 + 1 == 10
True
Workaround 2
>>> 0.99 < 0.3 + 0.3 + 0.3 + 0.1 < 1.01
True
Workaround 3
>>> decimal.Decimal('0.3') + decimal.Decimal('0.3') + decimal.Decimal('0.3') + decimal.Decimal('0.1') == decimal.Decimal('1.0')
True
quest_ likes this post
Reply
#7
(Jan-17-2021, 10:28 PM)bowlofred Wrote: Beware floating point math. Many decimals cannot be represented exactly. Either check for approximate solutions, or do your math with integers and then divide by 10 later. Otherwise you will run into problems.

>>> 0.3 + 0.3 + 0.3 + 0.1 == 1.0
False
Workaround 1
>>> 3 + 3 + 3 + 1 == 10
True
Workaround 2
>>> 0.99 < 0.3 + 0.3 + 0.3 + 0.1 < 1.01
True
Workaround 3
>>> decimal.Decimal('0.3') + decimal.Decimal('0.3') + decimal.Decimal('0.3') + decimal.Decimal('0.1') == decimal.Decimal('1.0')
True

Many thanks, I did not notice that before!!!
Reply
#8
Use integer 0 through 10 and convert to float when the values are used.
import itertools
four = []
for a, b, c in itertools.product(range(11), repeat=3):
    if (d := 10 - a - b - c) >= 0:
        four.append([a, b, c, d]) # <- Can convert to float here or when used
This code generates 1331 combinations of which 286 are valid.

If you want to be really efficient you can do this:
for a in range(11):
    for b in range(11-a):
        for c in range(11-a-b):
            four.append([a, b, c, 10-a-b-c])
The inner loop executes 286 times to give you the 286 possible number combinations.
buran and Serafim like this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Creating a loop with dynamic variables instead of hardcoded values FugaziRocks 3 1,430 Jul-27-2022, 08:50 PM
Last Post: rob101
  Create array of values from 2 variables paulo79 1 1,055 Apr-19-2022, 08:28 PM
Last Post: deanhystad
  variables vcnt, ocnt, and mcnt adding previous values and not resetting to 0 archanut 2 1,882 Feb-12-2021, 06:56 PM
Last Post: deanhystad
  Variables being overridden to initial values. p2bc 6 2,563 Oct-10-2020, 09:03 PM
Last Post: p2bc
  Print variable values from a list of variables xnightwingx 3 2,569 Sep-01-2020, 02:56 PM
Last Post: deanhystad
  Assign dynamic values to Variables srikanthpython 6 3,362 Jun-06-2020, 03:36 PM
Last Post: srikanthpython
  Using Excel Values As Variables for Equation dezmund 1 2,171 May-09-2019, 01:06 PM
Last Post: heiner55
  How many variables/values are limited to single assignment operator? Prabakaran141 1 2,000 Sep-06-2018, 03:32 PM
Last Post: Larz60+
  Storing and using UI variables values across files xenas 5 4,228 Mar-24-2017, 11:23 PM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020