2015-09-11 3 views
3

Я пытаюсь построить новый список поплавков из другого существующего списка поплавков. Ожидаемые содержание этого первого списка легче идентифицировать пример:Ошибка Python - In и Not In Syntax

price_list = [39.99, 74.99, 24.99, 49.99] 

Ожидаемо, после функции:

print new_price_list 
>>[29.99, 34.99, 44.99, 54.99, 59.99, 64.99, 69.99] 

Новый список получен, глядя на диапазон существующего списка и, начиная с с минимальным значением в существующем списке, добавляя поплавки + = 5.00, которые не находятся в существующем списке. Моя первая попытка решения была:

price_list = [39.99, 74.99, 24.99, 49.99] 

min_price = min(price_list) 

new_price_list = [] 
while min_price < max(price_list): 
    if min_price not in price_list: 
     new_price_list.append(min_price) 
    min_price += 5.00 

for price in new_price_list: 
    print price 

>>29.99 
>>34.99 
>>39.99 
>>44.99 
>>49.99 
>>54.99 
>>59.99 
>>64.99 
>>69.99 

И только для справки:

print new_price_list 
>>[29.99, 34.989999999999995, 39.989999999999995, 44.989999999999995, 49.989999999999995, 54.989999999999995, 59.989999999999995, 64.99, 69.99] 

В то же время, я определил, что я думаю, что это вопрос с тем, как MIN_PRICE в настоящее время по сравнению с пунктов в price_list. Мое неудобное решение проблемы заключается в следующем. Тем не менее, мне все еще интересно, если в любом случае для более эффективного выполнения этой задачи, как я пытался сделать в своей первоначальной догадке решение или, возможно, даже больше, используя понимание списка даже с min_price + = 5.00?

price_list = [39.99, 74.99, 24.99, 49.99] 

min_price = min(price_list) 

new_price_list = [] 
while min_price < max(price_list): 
    if int(min_price) not in [int(price) for price in price_list]: 
     new_price_list.append(int(min_price)) 
    min_price += 5.00 

better_price_list = [price + 0.99 for price in new_price_list] 
print better_price_list 

[29.99, 34.99, 44.99, 54.99, 59.99, 64.99, 69.99] 

Большое спасибо за помощь! С нетерпением ждем, когда узнаем это сообщество.

+5

так, где именно это ошибка синтаксиса? – UnholySheep

+0

Извинения @UnholySheep Я имел в виду это как «.... Синтаксис, ошибка» не обязательно <Синтаксическая ошибка>. Плохой выбор титула lol. – ian

ответ

2

Для генерации значений, мин и макс и создать генератор пользовательский диапазон:

mn = min(price_list) 

mx = max(price_list) 


def flt_rnge(start, stop, step): 
    start += step 
    while start < stop: 
     yield start 
     start += step 


print(list(flt_rnge(mn, mx, 5))) 

которая выводит следующее, которое не ошибкасинтаксиса, это выход магнезии:

[29.99, 34.989999999999995, 39.989999999999995, 44.989999999999995, 49.989999999999995, 54.989999999999995, 59.989999999999995, 64.99, 69.99] 

Если вы хотите, чтобы значение не было в вашем списке, вы можете использовать set, чтобы сохранить цены уже в своем списке, но при сравнении поплавков вы будете сталкиваться с floating-point-arithmetic-issues, и в этом случае всегда при работе с деньгами вы должны использовать decimal модуль:

price_list = [39.99, 74.99, 24.99, 49.99] 

mn = min(price_list) 
mx = max(price_list) 

from decimal import Decimal 
def flt_rnge(start, stop, step, l): 
    st = map(str, l) 
    start,stop,step = Decimal(str(start)),Decimal(str(stop)),Decimal(str(step)) 
    start += step 
    while start < stop: 
     if start not in st: 
      yield start 
     start += step 


print(list(flt_rnge(mn, mx, 5, price_list))) 
[Decimal('29.99'), Decimal('34.99'), Decimal('44.99'), Decimal('54.99'), Decimal('59.99'), Decimal('64.99'), Decimal('69.99')] 

вы печатаете вывод в своей первой части вопроса, так вы видите хорошо форматированный вывод, при печати списка после того, как вы видите магнезии, который показывает значение с плавающей точкой, хранящееся в действительности не равны до xx.99, так что все ваши if x not in list.

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

+1

Я уверен, что вам лучше не увеличивать один за другим в диапазоне с плавающей запятой, но каждый раз рассчитывать start + step * curstep. Пошаговые приращения значений с плавающей запятой, как правило, приводят к большему и большему накоплению ошибок; умножение стремится ограничить ошибку (особенно если шаг является «int» и может быть умножен точно, прежде чем добавлять его для запуска). Использование Decimal отрицает проблему; это хорошее общее решение. Вызов раунда (val, 2) на каждом поплавке в наборе и на каждое вставленное значение или тестирование на членство также будет работать в зависимости от величины значений. – ShadowRanger

+0

@ShadowRanger, имея дело с деньгами, я думаю, что десятичный модуль является самым безопасным способом. Первая часть была всего лишь примером того, как создать диапазон с поплавками и показать OP, что они видят результирующий вывод в списке –

+1

Абсолютно. 'decimal' - правильное решение. Плавающая точка - это дьявол, как правило. Единственная причина даже рассмотреть его - это узкоспециализированная проблема с высокими требованиями к производительности (но тогда вы, вероятно, используете numpy). – ShadowRanger

0

Нечто подобное, вероятно, что вы хотите ..

upper_bound = max(int(p) for p in price_list) 
lower_bound = min(int(p) for p in price_list) 
new_price_list = [(p+0.99) for p in range(lower_bound, upper_bound, 5) 
         if (p+0.99) not in price_list] 
-1

Действительно ли вы уверены, что все цены будут заканчиваться на .99? Если нет, то ваше решение и новое предложение будут недействительными по фактическим данным.

Я предлагаю вам сначала преобразовать цены в центах:

pennies_list = [round(100*p) for p in price_list] 

Теперь вы можете идти о вашей обычной бизнес поиска недостающих цен. Найдите значения min_price и max_price списка пенни, как показало polpak.

full_list = [p for p in range(min_price, max_price, 500) ] 
original_set = set(pennies_list) 
full_set = set(full_list) 
new_set = full_set - original_set 
new_price_list = list(new_set) 
0

Это другой способ добиться того, что вам нужно:

price_list = [39.99, 74.99, 24.99, 49.99] 

min_price = min(price_list) 
max_price = max(price_list) 

new_price_list = [min_price + 5.00] 
for i in new_price_list: 
    if i < max_price - 5.00: 
     num = i+5.00 
     num = round(num,2) 
     new_price_list.append(num) 
print new_price_list 

Выход:

[29.99, 34.99, 39.99, 44.99, 49.99, 54.99, 59.99, 64.99, 69.99]