Jes*_*ess 4 python dictionary list python-3.x
values/test/10/blueprint-0.png,2089.0,545.0,2100.0,546.0
values/test/10/blueprint-0.png,2112.0,545.0,2136.0,554.0
Run Code Online (Sandbox Code Playgroud)
我想要做的是读取一个.txt包含数百个值的文件,比如上面分享的值,创建一个字典,其密钥是前两个数字的值; 我的预期输出:
mydict = {
'10-0': [[2089,545,2100,545,2100,546,2089,546],
[2112,545,2136,545,2136,554,2112,554]],
}
Run Code Online (Sandbox Code Playgroud)
说明我们如何从4号去到8位数字,让我们看到他们x1,y1,x2,y2在第一,并且在输出它们合并为x1,y1,x2,y1,x2,y2,x1,y2
在实际数据中,我有数百个值,所以如果起始2个元素不同,我会有不同的键.假设.txt文件中的行开头,values/test/10/blueprint-1.png那么键是'10-1'.
我尝试过的:
import re
import itertools
file_data = [re.findall('\d+', i.strip('\n')) for i in open('ground_truth')]
print(file_data)
final_data = [['{}-{}'.format(a, b), list(map(float, c))] for a, b, *c in file_data]
new_data = {a: list(map(lambda x: x[-1], b)) for a, b in
itertools.groupby(sorted(final_data, key=lambda x: x[0]), key=lambda x: x[0])}
Run Code Online (Sandbox Code Playgroud)
但我得到了
ValueError: not enough values to unpack (expected at least 2, got 1)
Run Code Online (Sandbox Code Playgroud)
我似乎无法解决我的问题从一个简单的文件,其中包含这两行中的答案mydict.
请注意,以此行为例,values/test/10/blueprint-0.png,2089.0,545.0,2100.0,546.0我们将找到这些数字,[10, 0, 2089, 0, 545, 0, 2100, 0, 546, 0]并且0元素3,5,7和9中的s是无关紧要的,因为这些数字在列表中.这些可以通过打印看到file_data,就像我在上面的代码中所做的那样.
您需要使用更复杂的正则表达式来忽略小.0数值:
re.findall(r'(?<!\.)\d+', i)
Run Code Online (Sandbox Code Playgroud)
这使用负面的后视,忽略任何前面带有数字的数字..这将忽略.0,但如果有.01,那么.0(或.<digit>)之外的那些额外数字仍将被拾取.对于您的输入应该足够了.
我在这里使用常规循环来使代码更具可读性,并保持代码O(N)而不是O(NlogN)(不需要排序):
new_data = {}
with open('ground_truth') as f:
for line in f:
k1, k2, x1, y1, x2, y2 = map(int, re.findall(r'(?<!\.)\d+', line))
key = '{}-{}'.format(k1, k2)
new_data.setdefault(key, []).append([x1, y1, x2, y1, x2, y2, x1, y2])
Run Code Online (Sandbox Code Playgroud)
我x, y在这里硬编码你的组合,因为你似乎有一个非常具体的期望订单.
演示:
>>> import re
>>> file_data = '''\
... values/test/10/blueprint-0.png,2089.0,545.0,2100.0,546.0
... values/test/10/blueprint-0.png,2112.0,545.0,2136.0,554.0
... '''
>>> new_data = {}
>>> for line in file_data.splitlines(True):
... k1, k2, x1, y1, x2, y2 = map(int, re.findall(r'(?<!\.)\d+', line))
... key = '{}-{}'.format(k1, k2)
... new_data.setdefault(key, []).append([x1, y1, x2, y1, x2, y2, x1, y2])
...
>>> new_data
{'10-0': [[2089, 545, 2100, 545, 2100, 546, 2089, 546], [2112, 545, 2136, 545, 2136, 554, 2112, 554]]}
Run Code Online (Sandbox Code Playgroud)
一个很好的选择是将输入文件视为CSV格式!使用该csv模块是拆分列的好方法,之后您只需要处理第一个文件名列中的数字:
import csv, re
new_data = {}
with open('ground_truth') as f:
reader = csv.reader(f)
for filename, *numbers in reader:
k1, k2 = re.findall(r'\d+', filename) # no need to even convert to int
key = '{}-{}'.format(k1, k2)
x1, y1, x2, y2 = (int(float(n)) for n in numbers)
new_data.setdefault(key, []).append([x1, y1, x2, y1, x2, y2, x1, y2])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
59 次 |
| 最近记录: |