将代码简化为字典理解
Simplifying the code to a dictionary comprehension
在目录 images 中,图像命名为 - 1_foo.png , 2_foo.png, 14_foo.png,等等
图像经过 OCR 处理,文本提取通过以下代码存储在 dict
中 -
data_dict = {}
for i in os.listdir(images):
if str(i[1]) != '_':
k = str(i[:2]) # Get first two characters of image name and use as 'key'
else:
k = str(i[:1]) # Get first character of image name and use 'key'
# Intiates a list for each key and allows storing multiple entries
data_dict.setdefault(k, [])
data_dict[k].append(pytesseract.image_to_string(i))
代码按预期执行。
图片的名称中可以有不同的数字,范围从 1 到 99。
这可以减少到 dictionary comprehension
吗?
没有。字典理解中的每次迭代都会为键分配一个值;它无法更新现有值列表。字典理解并不总是更好——您编写的代码似乎已经足够好了。虽然也许你可以写
data_dict = {}
for i in os.listdir(images):
k = i.partition("_")[0]
image_string = pytesseract.image_to_string(i)
data_dict.setdefault(k, []).append(image_string)
是的。这是一种方法,但我不推荐它:
{k: d.setdefault(k, []).append(pytesseract.image_to_string(i)) or d[k]
for d in [{}]
for k, i in ((i.split('_')[0], i) for i in names)}
这可能是我能做到的最干净的了,但它仍然很糟糕。最好使用普通循环,尤其是像 Dennis 那样干净的循环。
略有不同(如果我滥用一次,我不妨再做两次):
{k: d.setdefault(k, []).append(pytesseract_image_to_string(i)) or d[k]
for d in [{}]
for i in names
for k in i.split('_')[:1]}
编辑:kaya3 现在发布了一个 good 一个使用字典理解的。我也会推荐我的。我真的只是我像 "Someone said it can't be done? Challenge accepted!".
这样的肮脏结果
在这种情况下itertools.groupby
会很有用;您可以按数字部分对文件名进行分组。但是让它工作并不容易,因为这些组在序列中必须是连续的。
这意味着在我们可以使用 groupby
之前,我们需要使用提取数字部分的键函数进行排序。这与我们要分组的键函数相同,因此单独编写键函数是有意义的。
from itertools import groupby
def image_key(image):
return str(image).partition('_')[0]
images = ['1_foo.png', '2_foo.png', '3_bar.png', '1_baz.png']
result = {
k: list(v)
for k, v in groupby(sorted(images, key=image_key), key=image_key)
}
# {'1': ['1_foo.png', '1_baz.png'],
# '2': ['2_foo.png'],
# '3': ['3_bar.png']}
将 list(v)
替换为 list(map(pytesseract.image_to_string, v))
用于您的用例。
在目录 images 中,图像命名为 - 1_foo.png , 2_foo.png, 14_foo.png,等等
图像经过 OCR 处理,文本提取通过以下代码存储在 dict
中 -
data_dict = {}
for i in os.listdir(images):
if str(i[1]) != '_':
k = str(i[:2]) # Get first two characters of image name and use as 'key'
else:
k = str(i[:1]) # Get first character of image name and use 'key'
# Intiates a list for each key and allows storing multiple entries
data_dict.setdefault(k, [])
data_dict[k].append(pytesseract.image_to_string(i))
代码按预期执行。
图片的名称中可以有不同的数字,范围从 1 到 99。
这可以减少到 dictionary comprehension
吗?
没有。字典理解中的每次迭代都会为键分配一个值;它无法更新现有值列表。字典理解并不总是更好——您编写的代码似乎已经足够好了。虽然也许你可以写
data_dict = {}
for i in os.listdir(images):
k = i.partition("_")[0]
image_string = pytesseract.image_to_string(i)
data_dict.setdefault(k, []).append(image_string)
是的。这是一种方法,但我不推荐它:
{k: d.setdefault(k, []).append(pytesseract.image_to_string(i)) or d[k]
for d in [{}]
for k, i in ((i.split('_')[0], i) for i in names)}
这可能是我能做到的最干净的了,但它仍然很糟糕。最好使用普通循环,尤其是像 Dennis 那样干净的循环。
略有不同(如果我滥用一次,我不妨再做两次):
{k: d.setdefault(k, []).append(pytesseract_image_to_string(i)) or d[k]
for d in [{}]
for i in names
for k in i.split('_')[:1]}
编辑:kaya3 现在发布了一个 good 一个使用字典理解的。我也会推荐我的。我真的只是我像 "Someone said it can't be done? Challenge accepted!".
这样的肮脏结果在这种情况下itertools.groupby
会很有用;您可以按数字部分对文件名进行分组。但是让它工作并不容易,因为这些组在序列中必须是连续的。
这意味着在我们可以使用 groupby
之前,我们需要使用提取数字部分的键函数进行排序。这与我们要分组的键函数相同,因此单独编写键函数是有意义的。
from itertools import groupby
def image_key(image):
return str(image).partition('_')[0]
images = ['1_foo.png', '2_foo.png', '3_bar.png', '1_baz.png']
result = {
k: list(v)
for k, v in groupby(sorted(images, key=image_key), key=image_key)
}
# {'1': ['1_foo.png', '1_baz.png'],
# '2': ['2_foo.png'],
# '3': ['3_bar.png']}
将 list(v)
替换为 list(map(pytesseract.image_to_string, v))
用于您的用例。