2016-12-20 5 views
1

У меня есть изображение (список списков), и я хочу вернуть средний цвет всего изображения. Я попытался с помощью почтовый индекс(), чтобы разрезать изображение на 3 части красным, зеленым, синим, но когда я запускаю код:проблема с получением среднего цвета (красный, зеленый, синий) из списка списков с использованием zip()

def average(image): 
    """Returns the average color of the pixels in the image""" 
    red = [] 
    green = [] 
    blue = [] 
    for r, g, b in zip(image): 
     red.append(r), green.append(g), blue.append(b) 
    average_color = (sum(red)/len(red)), (sum(green)/len(green)), \ 
        (sum(blue)/(len(blue))) 
    return average_color 

Он говорит:

ValueError: not enough values to unpack (expected 3, got 1). 

Я не уверен, что неправильный, сделал zip() сделать только 1 ломтик?

+0

Является ли 'образ' последовательностью' (красного, зеленого, синего) 'значений? –

ответ

1

Если image - это последовательность кортежей с значениями (r, g, b), вам необходимо применить целую последовательность в виде отдельных аргументов с помощью *args. Это создает 3 новые списки, с цветными полосами, разделенными для вас:

def average(image): 
    red, green, blue = zip(*image) 
    return (
     sum(red)/len(red), 
     sum(green)/len(green), 
     sum(blue)/(len(blue)) 

zip() объединяет значения из одного или нескольких итерируемых; Вы дали ему только один Iterable, так что вы просто получите то же значение обратно:

>>> sample = [('foo', 'bar', 'baz'), ('spam', 'ham', 'eggs')] 
>>> next(zip(sample)) 
('foo', 'bar', 'baz') 

Но если вы используете *args применить каждый из элементов, содержащихся в последовательности, как отдельного аргумента, как если бы вы назвали zip() с zip(args[0], args[0], ..., args[n]), фактически давая вам транспонированные столбцы строк:

>>> next(zip(*sample)) 
('foo', 'spam') 

где 'foo' и 'spam' первых значения двух кортежей в sample.