【问题标题】:Python - In and Not In List Syntax ErrorPython - 在列表中和不在列表中的语法错误
【发布时间】:2015-09-11 22:32:01
【问题描述】:

我正在尝试从另一个现有的浮动列表构建一个新的浮动列表。第一个列表的预期内容更容易通过示例识别:

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]

非常感谢您的帮助!期待更好地了解这个社区。

【问题讨论】:

  • 那么语法错误到底在哪里?
  • 道歉@UnholySheep 我的意思是“....语法错误”不一定是。标题选择不当哈哈。

标签: python list list-comprehension


【解决方案1】:

要生成值、最小值和最大值并创建自定义范围生成器:

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)))

以下不是语法错误的输出,是repr输出:

[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 的 repr 后打印列表时,您会看到格式正确的输出,所以所有你的if x not in list

在处理金钱时,你应该从一开始就使用十进制模块。

【讨论】:

  • 我很确定你最好不要在基于浮点数的范围内逐一递增,而是每次都计算 start + step * curstep。浮点值的逐步递增往往会导致越来越大的误差累积;乘法往往会限制错误(特别是如果 step 是int 并且可以在将其添加到开始之前精确地相乘)。使用 Decimal 可以解决问题;这是一个很好的通用解决方案。根据值的大小,对集合中的每个浮点数以及插入的每个值或成员资格测试调用 round(val, 2) 也将起作用。
  • @ShadowRanger,在处理金钱时,我认为十进制模块是最安全的方法。第一部分只是一个示例,说明如何使用浮点数创建范围并向 OP 显示他们在列表中看到 repr 输出
  • 当然。 decimal 是正确的解决方案。通常,浮点是魔鬼。甚至考虑它的唯一原因是具有高性能要求的范围狭窄的问题(但无论如何你可能正在使用 numpy)。
  • 谢谢大家谢谢!小数在这里看起来很棒。
【解决方案2】:

这样的东西可能是你想要的..

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]

【讨论】:

    【解决方案3】:

    这是实现您需要的另一种方式:

    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]
    

    【讨论】:

      【解决方案4】:

      你真的保证价格都会以 .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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-21
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        • 1970-01-01
        相关资源
        最近更新 更多