Эффективный способ разделения значений R, G и B из файла, содержащего значения RGB (без NumPy)

#python #regex #python-2.7

#python #регулярное выражение #python-2.7

Вопрос:

У меня есть файл, содержащий значения RGB. Нравится,

Пример изображения Data.txt файл

Каждая строка содержит триплеты (например, 255,255,255), разделенные пробелами.
Каждый триплет содержит три целых числа, разделенных запятыми. Это целое число соответствует значениям R (‘RED’), G (‘GREEN’) и B (‘BLUE’). Все целые числа меньше 256.

 255,255,255 250,250,250 254,254,254 250,250,250 
255,255,255 253,253,253 255,255,255 255,255,255 
251,251,251 247,247,247 251,251,251 250,250,250
195,195,195 191,191,191 195,195,195 195,195,195
255,255,255 253,253,253 254,254,254 255,255,255 
255,255,255 254,254,254 239,239,239 240,240,240
238,238,238 254,254,254 255,255,255 255,255,255
 

Обработанный вывод должен выглядеть следующим образом:
КРАСНЫЙ = ['255','250','254','250','255','253','255',............,'254','255','255']
ЗЕЛЕНЫЙ = ['255','250','254','250','255','253','255',............,'254','255','255']
СИНИЙ = ['255','250','254','250','255','253','255',............,'254','255','255']
RGB_Nx3_MATRIX = [['255','255','255'],['250','250','250'],['254','254','254'].....['255','255','255']]

Мой код работает нормально.

 import re

file_object = open('Image Data.txt','r') 

RED_VECTOR = []         #SEQUENTIALLY STORES ALL 'R' VALUES
GREEN_VECTOR = []       #SEQUENTIALLY STORES ALL 'G' VALUES
BLUE_VECTOR = []        #SEQUENTIALLY STORES ALL 'B' VALUES

RGB_Nx3_MATRIX = []     #Nx3 MATRIX i.e. ['R','G','B'] N times

for line in file_object:
    SPACE_split_LIST = line.split()

    for pixel in SPACE_split_LIST:
        RGB = re.findall(r',?(d ),?',pixel)
        RED_VECTOR  = [RGB[0]]
        GREEN_VECTOR  = [RGB[1]]
        BLUE_VECTOR  = [RGB[2]]

        RGB_Nx3_MATRIX  = [RGB]




#RESULTS

#print RED_VECTOR
#print GREEN_VECTOR
#print BLUE_VECTOR

#print "------------------"

#print RGB_Nx3_MATRIX
 

Что я ищу?

Мне нужен лучший и эффективный способ сделать это. Я хочу избежать использования двух циклов for.

Комментарии:

1. Этот вопрос, похоже, не по теме, поскольку речь идет об улучшении уже работающего кода. Это было бы лучше подходит для codereview.stackexchange.com .

Ответ №1:

вы можете избежать использования регулярных выражений

 f =open('Image Data.txt','r')                 

R=[]                                 
G=[]                                 
B=[]                                 
for line in f:                       
    for color_set in line.split():       
        r,g,b = color_set.split(',')     
        R =[r]                       
        G =[g]                       
        B =[b]                       

print B
 

вывод

 ['255', '250', '254', '250', '255', '253', '255', '255', '251', '247', '251', '250', '195', '191', '195', '195', '255', '253', '254', '255', '255', '254', '239', '240', '238', '254', '255', '255']
 

Ответ №2:

Если вас в основном интересует матрица, вы можете сделать это почти в одной строке:

 with open('Image Data.txt','r') as file_h:
    rgb_matrix = [triple.split(',') for line in file_h for triple in line.strip().split()]
 

что должно быть довольно эффективным. Вы также можете расширить это с помощью другого цикла, чтобы преобразовать их в целые числа.

 with open('Image Data.txt','r') as file_h:
    rgb_matrix = [[int(num) for num in triple.split(',')] for line in file_h for triple in line.strip().split()]
 

Если вам действительно нужны отдельные цвета, вы можете легко получить их как:

 red = [row[0] for row in rgb_matrix]
green = [row[1] for row in rgb_matrix]
blue = [row[2] for row in rgb_matrix]
 

Ответ №3:

Почему вы хотите избежать использования двух циклов for ? Циклы For по своей сути не являются неэффективными. Однако вызов функции для каждой строки (например, re.findall) может стать очень неэффективным.

Особенно при работе с большими файлами или обработке пикселей всегда лучше придерживаться простых функций и арифметики, а не дорогостоящих вызовов функций. Вместо этого вы можете сделать следующее:

 for line in file:
    split = line.split(' ')
    for s in split:
        r,g,b = s.split(',')
        r_vector.append(r)
        g_vector.append(g)
        b_vector.append(b.split('')[0]) <<<<Keep in mind, every line will have a 'n' newline char
 

РЕДАКТИРОВАТЬ: Спасибо @Ashoka Lella за указание на то, что каждая строка содержит несколько наборов rgb.

Комментарии:

1. Первый столбец, разделенный пробелом, не полностью красный. Это r, g,b. Каждая строка имеет формат r, g, br, g, br, g, b