【问题标题】:List comprehension to update values if condition is met [duplicate]如果满足条件,列表理解以更新值[重复]
【发布时间】:2021-06-10 18:26:01
【问题描述】:

我有以下列表和变量 i:

probs = [1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9]
i = 3

我想将变量 i 中给出的索引的列表中的值更改为 3/9,并将其余值更改为 8/9。 因此,在上述条件下所需的结果将是:

probs = [8/9, 8/9, 8/9, 3/9, 8/9, 8/9, 8/9, 8/9, 8/9]

为了提高效率,我更喜欢使用列表理解来执行此操作,有什么想法吗?

【问题讨论】:

  • 列表中的值是字符串对吗?并且您将值转换为 3/9 和 8/9,或者您想要乘以 3 和 8
  • 这些值是浮点数,我想转换这些值,而不是相乘。
  • “我更喜欢通过列表理解来提高效率” - 嗯,什么?列表理解是much less efficient,而不是列表重复(与您接受的答案中的列表理解相比)。
  • 使用列表解析比 lst = [8/9] * 9 ; lst[i] = 1/9 慢大约 5 倍 - 使用更长的列表会变得更糟。

标签: python list indexing list-comprehension


【解决方案1】:

这是一个满足您要求的列表理解:

probs = ["1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9"]
i = 3

probs = ["3/9" if idx == i else "8/9" for idx in range(len(probs))]
print(probs)
# Prints ['8/9', '8/9', '8/9', '3/9', '8/9', '8/9', '8/9', '8/9', '8/9']

请注意,我将分数转换为字符串,否则它们将被打印为浮点数。如果你想让它们成为浮点数,你可以这样做:

probs = [1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9, 1/9]
i = 3

probs = [3/9 if idx == i else 8/9 for idx in range(len(probs))]
print(probs)
# Prints [0.8888888888888888, 0.8888888888888888, 0.8888888888888888, 0.3333333333333333, 0.8888888888888888, 0.8888888888888888, 0.8888888888888888, 0.8888888888888888, 0.8888888888888888]

另外,请注意,这个列表推导实际上并不比普通的 for 循环快。

【讨论】:

  • “列表推导实际上并不比普通的 for 循环快” - 你如何在这里写一个同​​样快的普通 for 循环?
  • @Manuel for idx in range(len(probs)): probs[idx] = 3/9 if idx == i else 8/9
  • 好的,是的,我实际上已经测试过那个,它甚至比你的列表 comp一点(都比列表慢 much重复解决方案我showed earlier,顺便说一句)。不过,这在 Python 中是一个非常不寻常的循环,因为您忽略了原始元素。我不会称之为“正常”。 “通常”的普通 for 循环 构建 列表(即,与列表组合相同的工作) 比等效的列表组合慢。
  • @Manuel 好吧,我的异常循环的原因是 OP 想要改变 probs,而不是创建一个新列表。
  • 是的,完全没问题。这是不寻常的,因为不寻常的任务。只是你的陈述听起来很笼统,好像你在这里谈论的不仅仅是任务,我会说一般来说这不是真的。
【解决方案2】:

使用enumerate()

new_probs = ['3/9' if i == indx else '8/9' for indx, val in enumerate(probs)]
print(new_probs)

【讨论】:

    【解决方案3】:

    我建议使用 Python 的 fractions 模块进行概率计算。

    因此您的解决方案可能是:

    from fractions import Fraction
    probs = ["1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9", "1/9"]
    # rather than integer convert it to Fraction, or simply use fractions only from beginning.
    probs = [Fraction(i) for i in probs]  # convert like this
    # or use directly as below:
    probs = [Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9)]
    

    我相信你很有可能必须进行数学运算,所以你可以这样做:

    In [12]: print(probs)
    [Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9), Fraction(1, 9)]
    
    In [13]: i = 3
    
    In [15]: new_probs = [Fraction(3, 9) if prob==i else Fraction(8, 9) for prob in probs]
    
    In [16]: print(new_probs)
    [Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9)]
    

    或者假设您实际上是在执行 1 - Probability 的运算并乘以 3 来匹配,那么它仍然可以使用带有运算的分数,就像您期望使用概率函数执行的那样:

    In [17]: new_probs = [3*prob if prob==i else 1-prob for prob in probs]
    
    In [18]: print(new_probs)
    [Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(2, 3), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9), Fraction(8, 9)]
    

    【讨论】:

      【解决方案4】:

      您可以使用列表推导式中的表达式来做到这一点。

      probs = [3 / 9 if i == index else 8 / 9 for index, _ in enumerate(probs)]
      

      【讨论】:

        猜你喜欢
        • 2019-07-05
        • 2020-03-05
        • 1970-01-01
        • 2014-02-11
        • 2019-08-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-25
        • 2023-03-14
        相关资源
        最近更新 更多