I am reading from an excel file and require the generation of a list to pull from where it has every integer in a range to the number read as well as a specific decimal between each integer.
For instance, if I read that I require 2.3 units of x, then I would like to generate a list in range 0 to 2.3 that has [0, 0.3, 1.0, 1.3, 2.0, 2.3].
I have thought about adding two lists together:
Units = 3.3
ListIntegers = list(range(math.ceil(Units)))
ListFloats = list(range()) # Here I would need to create the 0.3, 1.3, 2.3, and 3.3
FinalList = ListIntegers ListFloats
FinalList.sort() # This will put my list back in numerical order
- How would I create that list of specific float values?
- Is there a better way to do this?
CodePudding user response:
You can use itertools.chain.from_iterable:
import itertools
Units = 5.8
j = round(Units%1, 1)
list(itertools.chain.from_iterable((i, i j) for i in range(int(Units) 1)))
Output:
[0, 0.8, 1, 1.8, 2, 2.8, 3, 3.8, 4, 4.8, 5, 5.8]
CodePudding user response:
A one-liner:
x = 2.3
a = sorted([i for i in range(int(x) 1)] [(x - i) for i in range(int(x) 1)])
This creates a following list:
[0, 0.2999999999999998, 1, 1.2999999999999998, 2, 2.3]
This is due to floating-point operation precision. To solve this, you'd have to round numbers in the process (as you can see, even rounding to 10th decimal place gives the result you want)
x = 2.3
a = sorted([i for i in range(int(x) 1)] [round(x - i, 10) for i in range(int(x) 1)])
Result:
[0, 0.3, 1, 1.3, 2, 2.3]
CodePudding user response:
To complete your snippet:
import math
Units = 3.3
ListIntegers = list(range(math.ceil(Units)))
decimal = round(Units - math.floor(Units), 1)
ListFloats = []
for integer in ListIntegers:
ListFloats.append(integer decimal)
FinalList = ListIntegers ListFloats
FinalList.sort()
CodePudding user response:
Surely not the best way, but this first comes to mind:
Units = 2.3
frac, _ = math.modf(Units)
result = []
curr = 0
for i in range(int(Units)*2 2):
if i % 2 == 1:
result.append(curr)
curr = (1 - frac)
else:
result.append(curr)
curr = frac
print(result)
CodePudding user response:
How's this?:
import math
Units = 5.8
addition = float("0." str(Units).split(".")[1])
intList = list(range(math.ceil(Units)))
finalList = intList [x addition for x in intList]
finalList.sort()
print(finalList)
Output:
[0, 0.8, 1, 1.8, 2, 2.8, 3, 3.8, 4, 4.8, 5, 5.8]
Edit
Per funnydman and Nin17 ... the addition
part could be dirty. You could change to something like the below. The assumption is that Units
will always be a float (have a decimal) because we are splitting it at that decimal to find the number of decimals points.
import math
Units = 6.8923
addition = Units%1
decimalLen = len(str(Units).split(".")[1]) # Find length of decimals past the decimal point for rounding purposes
intList = list(range(math.ceil(Units)))
finalList = intList [x round(addition, decimalLen) for x in intList]
finalList.sort()
print(finalList)
Output:
[0, 0.8923, 1, 1.8923, 2, 2.8923, 3, 3.8923, 4, 4.8923, 5, 5.8923, 6, 6.8923]
CodePudding user response:
Regarding your questions, I can say that
There are several algorithms to perform the same task. It all depends on what you fancy.
There's always space for improvements.
If I understand you correctly, the solution I came up with doesn't use if-elses, sorting nor list concatenation.
It generates a list with the double of size basing on the integer part of the Unit
(except from 0 which doubles anyway). Uses only one math import modf
and some operations, such as //
, **
and %
and a list comprehension.
from math import modf
Unit = 3.3
Decimal, Integer = modf(Unit)
transform = lambda i, d: round(i**(i%2)//2 (i//2 d)**(1-i%2),2)
a = [transform(i, Decimal) for i in range(-1, 2*int(Integer) 1)]
print(a)