【问题标题】:Changing several elements in a list using list comprehension使用列表推导更改列表中的多个元素
【发布时间】:2020-03-26 09:39:26
【问题描述】:

一个例子:

example = [None, b'1', b'2', b'3', b'4', b'1', None, None, b'8', b'56', b'66', b'77', b'1', None]

我需要通过以下方式更改此列表中的值:bytes 应转换为 intNone 应转换为 0,并且每第 6 和第 7 个元素转换为 bool。预期输出:

expected_output = [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]

我的尝试:

[int(value) if value else bool(value) if index in (5,6) else 0 for index, value in enumerate(example)]

结果:

[0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, 0, 0]

我知道这部分代码有问题:

[int(value) if value else bool(value) if index in (5,6) else 0 for index, value in enumerate(example)]
                                       ^
                                       |
                                       |

如何将每 6 个和第 7 个元素更改为 bool

【问题讨论】:

    标签: python type-conversion list-comprehension


    【解决方案1】:

    您需要检查索引模 7(每组中的元素数)是 5 还是 6。但您还需要首先这样做,因为 b'1' 也通过了 if value 测试:

    [bool(value) if index % 7 in (5,6) else int(value) if value else 0 for index, value in enumerate(example)]
    

    输出:

    [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]
    

    【讨论】:

    • 感谢您的帮助。这对我有帮助。
    • @MrOldSir 不用担心 - 我很高兴它有用。
    【解决方案2】:

    你添加到这个列表推导中的逻辑越多,它就会变得越不可读。我建议您在这里使用正常的if/elif 声明:

    for ix, i in enumerate(example):
        if ix % 7 in (5,6):
            example[ix] = bool(i)
        elif not i:
            example[ix] = 0
        elif isinstance(i, bytes):
            example[ix] = int(i)
    

    print(example)
    # [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]
    

    【讨论】:

      【解决方案3】:

      基本

      您可以使用%(模) 运算符实现旋转

      example = [
          None, b'1', b'2', b'3', b'4', b'1', None,
          None, b'8', b'56', b'66', b'77', b'1', None,
      ]
      
      results = [
          bool(value) if index % 7 in {5, 6} else
          int(value) if value else 0
          for index, value in enumerate(example)
      ]
      print(results)
      

      输出:

      [0, 1, 2, 3, 4, True, False, 0, 8, 56, 66, 77, True, False]
      

      Python 风格

      但是,还有一些更 Pythonic 的方式:

      import itertools
      
      example = [
          None, b'1', b'2', b'3', b'4', b'1', None,
          None, b'8', b'56', b'66', b'77', b'1', None,
      ]
      converters = itertools.cycle(itertools.chain(
          itertools.repeat(lambda x: int(x) if x else 0, 5),
          itertools.repeat(bool, 2),
      ))
      
      results = [
          converter(value) for converter, value in zip(converters, example)
      ]
      print(results)
      

      输出:同上。

      说明

      • itertools.cycle:做一个循环迭代器。
      • itertools.chain:连接可迭代对象。
      • itertools.repeat: 制作迭代器,按指定次数重复。
      • 所以converters = ... 部分表示:lambda x: int(x) if x else 0 函数执行五次,bool 执行两次,并重复此循环!
      • 您可以为每个位置添加多个规则,而不需要复杂的if-else

      【讨论】:

        猜你喜欢
        • 2023-03-03
        • 1970-01-01
        • 2013-09-27
        • 2020-05-07
        • 2020-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多