【问题标题】:Is there a way to rewrite a list comprehension as a for loop? [closed]有没有办法将列表理解重写为 for 循环? [关闭]
【发布时间】:2016-07-24 03:14:00
【问题描述】:

我有这样一行代码:

list1=[string1[i:i+int1] for i in range(0, len(string1), int1)]

我记得我的老师说过,当有“for”时,我们应该开始换行 那么,有没有办法编写如下代码:

for i in range(0, len(string1), int1):
    #something here

还是别的什么?

【问题讨论】:

  • 请阅读list comprehensions
  • 你老师的建议过于简单化了。当有 for statement 时,您应该开始一个新行,但表达式内的 for 不是 for 语句的一部分;它是列表理解的一部分。
  • 我几乎可以肯定你的老师并不是说你应该放弃所有的list comprehensions 来支持明确地构建listfor 循环。如果他们这样做了,他们并没有真正教你 Python。
  • 毫无疑问你的老师试图简化事情。我会将您的标题更新为您在此处实际提出的问题。

标签: python python-3.x


【解决方案1】:

你必须先创建空列表,然后为每次迭代追加。

list1 = []
for i in range(0, len(string1), int1):
    list1.append(string1[i:i+int1])

【讨论】:

    【解决方案2】:

    您的意思是从list-comprehension 中提取一个无聊的旧常规for loop

    list1=[string1[i:i+int1] for i in range(0, len(string1), int1)]
    

    变成:

    list1 = list()
    for i in range(0, len(string1), int1):
        list1.append(string1[i:i+int1])
    

    如果您想在迭代数据时添加异常处理、日志记录或更复杂的功能或行为,这将非常有用。

    例如:

    list1 = list()
    for i in range(0, len(string1), int1):
        log.info('in loop: i={}'.format(i))
        try:
            data = string1[i:i+int1]
        except:
            log.error('oh no!')
            # maybe do something complex here to get some data anyway?
            data = complex_function(i)
        log.debug('appending to list: data={}'.format(data))
        list1.append(data)
    

    但一般来说,列表理解是一种完全合法的书写方式。

    【讨论】:

    • 或者,可以编写一个函数并执行[somefunction(val) for val in values]。当然,假设这适合这种情况。作为另一种可能合适的选择,而不是返回列表,可以yield data 并让生成器退出交易。
    • []list() 更有效。见why
    • @zondo: 也方便地避免了人名屏蔽list 的问题,尽管理想情况下,他们一开始就不会这样做。 :-) 也就是说,list() 相对于[] 的增量成本非常小,在我的机器上增加了大约 60-70 ns(诚然,比 [] 的基本成本增加了 2-3.5 倍~20 -30 ns,但除了最热的循环之外,其他所有循环都不太重要)。
    • 我会增加可读性。对我来说,something = []something = list() 更容易识别。
    【解决方案3】:

    该列表理解将转换为:

    l = []
    for i in range(0, len(string1), int1):
        l.append(string1[i:i+int1])
    

    【讨论】:

      【解决方案4】:

      有点脏,但是将集合拆分为固定大小的子集合的不错选择。

      from itertools import zip_longest
      
      l = []
      for chunk in zip_longest(*([iter(string1)]*int1), fillvalue=''):
          l.append(''.join(chunk))
      

      【讨论】:

        【解决方案5】:
        g = (string[i:i+int1] for i,char in enumerate(string) if i % int1 == 0)
        l = list(g)
        

        不要在处理索引时使用len(iterable)。为此使用enumerate()。它产生(index, item)。这是高效且 Pythonic 的。

        在使用for 循环时应该换行的想法可能是其他一些语言的惯用语,例如 C、C++。但不是在python中。列表推导来自 FP 的 Haskell 世界。所以他们来的时候很优雅。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-29
          • 2016-09-15
          • 1970-01-01
          • 2020-12-17
          • 1970-01-01
          相关资源
          最近更新 更多