【问题标题】:How to make list comprehensions more readable?如何使列表推导更具可读性?
【发布时间】:2020-02-20 04:32:30
【问题描述】:

我在下面有这段代码,如果你是 python 新手,我觉得有点难以理解。

如何让 Python 新手(学生)更容易阅读

def right_inwrongplace(userGuess, number):
    correct_places = [True if v == number[i] else False for i, v in enumerate(userGuess)]
    g = [v for  i, v in enumerate(userGuess) if not correct_places[i]]
    n = [v for  i, v in enumerate(number) if not correct_places[i]]
    return len([i for i in g if i in n])

【问题讨论】:

  • 写普通循环有什么问题?
  • 尝试使用v == number[i] 而不是True if v == number[i] else False
  • 您可以使用indexvalue 代替iv 使其更明确(也可以使用其他字母)
  • 初学者理解“pythonic”就地列表创建循环。在 SO 上经常可以看到 - 有人用神秘的就地列表创建来回答 python 问题,然后 OP 做出响应。 “啊?!”。长期创建列表。同样正如@OferSadan 指出的那样,使用更有意义的变量名称 - 数字迭代器的i 很好,但vgn 不是。代码 cmets 也在哪里?
  • @Kingsley 我要补充一点,人们经常错误地认为将所有内容都转换为 列表理解 是 Python 的意思,但事实并非如此。如果有些东西是不可读的,那就不是 Pythonic!那是python的核心价值之一!可读性很重要!现在,简单的映射/过滤操作通常在 Python 上表示为列表推导式,但如果它变得笨拙,那么该语言结构的整个目的就会被颠覆。

标签: python python-3.x python-2.7 list list-comprehension


【解决方案1】:

以下是一些改进:

  • True if x else False 只是 bool(x) 或者,正如您已经在进行比较,只是那个表达式,即 v == number[i]
  • 由于您是通过位置索引访问数字,因此您只需 zip 两个序列即可。

所以首先你会得到:

correct_places = [x == y for x, y in zip(userGuess, number)]

zip 相同的参数适用于以下两个推导式(您可以再次迭代原始字符串):

g = [x for x, y in zip(userGuess, number) if x != y]
n = [y for x, y in zip(userGuess, number) if x != y]

鉴于这两次基本上是相同的理解,并且我们不再需要correct_places,我们可以改为执行以下操作:

g, n = zip(*[(x, y) for x, y in zip(userGuess, number) if x != y])

那你可以sum代替len

return sum(x in n for x in g)

所以基本上你可以使用下面的代码:

g, n  = zip(*(xy for xy in zip(userGuess, num) if xy[0] != xy[1])
return sum(x in n for x in g)

【讨论】:

  • g, n = zip(*[...]) 很可爱,但很神秘。我不认为这是一种改进。但是,使用zip 迭代两个对应的对好。
  • @juanpa.arrivillaga 是的,所以最好保留两个独立的理解:-) 一旦你认识到zip(*[...]) 基本上转置了给定的序列,它就变得更清晰了(在某些情况下至少)。我不时为此目的使用它,但与理解一起它似乎有点沉重。但是我发现transposed = zip(*sequence) 是可读的。
  • 看,我的标准是“如果一个不熟悉 python 的有能力的程序员会很难理解它,它是不可读的”。当然,您可以争辩说某些成语在一种语言中很常见,我只是不确定transposed = zip(*sequence) 是其中之一。我认为这是一个很好的例子,说明这个问题过于基于意见,老实说,它更适合 CodeReview
猜你喜欢
  • 1970-01-01
  • 2010-11-29
  • 2019-09-29
  • 1970-01-01
  • 2021-10-30
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
相关资源
最近更新 更多