[英]Creating lists from data file
I have a pre-defined list that gives data in the form of (min, max, increment). 我有一个预定义的列表,该列表以(最小,最大,增量)形式提供数据。 for example: 例如:
[[0.0 1.0 0.1 #mass
1.0 5.0 1.0 #velocity
45.0 47.0 1.0 #angle in degrees
0.05 0.07 0.1 #drag coeff.
0.0 0.0 0.0 #x-position
0.0 0.0 0.0]] #y-postion
and this goes on a for a few more variables. 并继续进行其他一些变量。 Ideally I want to take each one in as an individual variable declaration and create a finite list of each value in the given range. 理想情况下,我想将每个变量都当作一个单独的变量声明,并为给定范围内的每个值创建一个有限列表。
For example, mass would be: 例如,质量为:
m = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
this way I can utilize itertools.combinations((m, x, b,...), r)
to create all possible combinations given the various possibilities of each variable. 这样,我可以利用itertools.combinations((m, x, b,...), r)
在给定每个变量各种可能性的情况下创建所有可能的组合。
Any suggestions? 有什么建议么?
You wrote the list as a flat list, with all numbers on the same level 您将列表写为平面列表,所有数字都在同一级别
[[0.0 1.0 0.1 1.0 5.0 1.0 45.0 47.0 1.0 ...]]
but it's possible you meant to write it as a nested list 但您可能打算将其写为嵌套列表
[[0.0, 1.0, 0.1], [1.0, 5.0, 1.0], [45.0, 47.0, 1.0], ...]
so I'll show both solutions. 所以我将展示两种解决方案。 Please let me know how your data/list is actually structured. 请让我知道您的数据/列表的实际结构。
Python's range
function doesn't support floats, but you can use NumPy's arange
. Python的range
函数不支持浮点数,但是您可以使用NumPy的arange
。
The try ... except
part is for your unchanging values like 0.0 0.0 0.0 #x-position
. try ... except
部分用于保持不变的值,例如0.0 0.0 0.0 #x-position
。
Flat list solution: 平面清单解决方案:
flat_list = [0.0, 1.0, 0.1,
1.0, 5.0, 1.0,
45.0, 47.0, 1.0,
0.05, 0.07, 0.1,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0]
import numpy as np
incremented_lists = []
for i in range(0, len(flat_list), 3): # Step in threes
minimum, maximum, increment = flat_list[i:i+3]
try:
incremented_list = list(np.arange(minimum, maximum + increment, increment))
except ZeroDivisionError:
incremented_list = [minimum]
incremented_lists.append(incremented_list)
Nested list solution: 嵌套列表解决方案:
nested_list = [[0.0, 1.0, 0.1],
[1.0, 5.0, 1.0],
[45.0, 47.0, 1.0],
[0.05, 0.07, 0.1],
[0.0, 0.0, 0.0],
[0.0, 0.0, 0.0]]
import numpy as np
incremented_lists = []
for sub_list in nested_list:
minimum, maximum, increment = sub_list
try:
incremented_list = list(np.arange(minimum, maximum + increment, increment))
except ZeroDivisionError:
incremented_list = [minimum]
incremented_lists.append(incremented_list)
Running either of these with Python 2.7 or Python 3.3 gets this: 使用Python 2.7或Python 3.3运行以下任一命令均可:
incremented_lists: [[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
[1.0, 2.0, 3.0, 4.0, 5.0],
[45.0, 46.0, 47.0],
[0.05, 0.15],
[0.0],
[0.0]]
The [0.05, 0.15]
is probably undesirable, but I think your huge 0.1 increment for the drag coefficient is more likely a typo than something I should make the code handle. [0.05, 0.15]
可能是不希望的,但是我认为阻力系数的0.1巨大增量比我应该使代码处理的东西更容易出现错字。 Please let me know if you would like the code to handle unnatural increments and avoid overshooting the maximum. 请让我知道您是否希望代码处理不自然的增量并避免超出最大值。 One way to handle that would be to add incremented_list = [x for x in incremented_list if x <= maximum]
right before incremented_lists.append(incremented_list)
, though I'm sure there's a cleaner way to do it. 处理该问题的一种方法是,在incremented_lists.append(incremented_list)
之前,立即添加incremented_list = [x for x in incremented_list if x <= maximum]
。
Not sure about you list structure, if you do need to take slices you can use itertools.islice and store all lists in a dict: 不确定列表结构,如果确实需要切片,则可以使用itertools.islice并将所有列表存储在dict中:
from itertools import islice
l = iter([0.0, 1.0, 0.1, #mass
1.0, 5.0, 1.0,#velocity
45.0 ,47.0, 1.0, #angle in degrees
0.05, 0.07, 0.1, #drag coeff.
0.0, 0.0 ,0.0 ,#x-position
0.0 ,0.0, 0.0])#y-postion
d = {}
import numpy as np
for v in ("m","v","and","drg","x-p","y-p"): # put all "variable" names in order
start, stop , step = islice(l, None, 3)
# or use next()
# start, stop , step = next(l), next(l), next(l)
if stop > start: # make sure we have a step to take
# create key/value pairing
d[v] = np.arange(start, stop + 1,step)
else:
# add empty list for zero values
d[v] = []
print(d)
{'x-p': [], 'drg': array([ 0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85,
0.95, 1.05]), 'and': array([ 45., 46., 47.]), 'v': array([ 1., 2., 3., 4., 5.]), 'y-p': [], 'm': array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ,
1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9])}
You can also create your own range that will take a float as a step: 您还可以创建自己的范围,以浮动为单位:
def float_range(start=0, stop=None, step=1):
while start <= stop:
yield start
start += step
Then call it with list(start, stop,step)
, but you need to be careful when dealing with floats because of Floating Point Arithmetic: Issues and Limitations 然后用list(start, stop,step)
调用它,但是在处理浮点数时需要小心,因为浮点算术:问题和局限性
I can't think of any existing format supporting your desired input -- with spaces as separator, newlines breaking sub-lists, and comments actually meaningful as you appear to desire the to define the sub-lists' names. 我想不出任何支持您想要的输入的现有格式-用空格作为分隔符,换行符打破子列表,并且在您似乎希望定义子列表名称时,注释实际上是有意义的。 So, I think you'll have to code your own parser, eg: 因此,我认为您必须编写自己的解析器,例如:
import re, numpy as np
res_dict = {}
with open('thefile.txt') as f:
for line in f:
mo = re.match(r'[?[(\S+)\s*(\S+)\s*(\S+)\s*#(\w)', line)
keybase = mo.group(4)
keyadd = 0
key = keybase
while key in res_dict:
key = '{}{}'.format(keybase, keyadd)
keyadd += 1
res_dict[key] = np.arange(
float(mo.group(1)),
float(mo.group(2)),
float(mo.group(3)),
)
This won't give you a top-level variable m
as you mention -- but rather a better-structured, more robust res_dict['m']
instead. 正如您所提到的,这不会给您一个顶级变量m
,而是一个结构更好,更可靠的res_dict['m']
。 If you insist on making your code brittle and fragile, you can globals().update(res_dict)
to make it so:-)... 如果您坚持要使代码脆弱易碎,则可以使 globals().update(res_dict)
变为:-)...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.