【问题标题】:Multiple list comprehension into single list comprehension多个列表理解到单个列表理解
【发布时间】:2017-07-13 21:44:47
【问题描述】:

我正在尝试使用列表推导来更改列表的值,我可以通过使用 3 个列表推导来做到这一点

clr = [1,2,2,1,3,1,2,3]
clr= ["green"  if i== 1 else i for i in clr]
clr = ["yellow"  if i==2 else i for i in clr]
clr = ["black"  if i == 3 else i for i in clr]

使用下面提到的代码会引发语法错误

clr = ["green"  if i== 1 else "yellow"  if i==2 else "black"  if i == 3 for i in clr]

有没有更好的办法?

【问题讨论】:

  • 你没有说抛出了什么错误。在询问错误时,您应该始终在问题中包含完整的回溯!无论如何,你忘记了最后的else 部分:... else "black" if i == 3 else i for i in clr]。但威廉的解决方案更好。
  • 我真的不喜欢你有这样的代码 clr = [... for i in clr] 并且你从不提供 clr 的初始值。

标签: python list list-comprehension


【解决方案1】:

是的。例如,您可以定义字典

the_dic = { 1 : 'green', 2 : 'yellow', 3 : 'black' }

然后执行映射,例如:

clr = [<b>the_dic.get(i,i)</b> for i in clr]

或者通过使用map(..)(在中,它作为生成器工作(因此很懒惰):

clr = <b>map(the_dic.get</b>,clr<b>)</b>

这将插入Nones,以防clr 中的元素不在字典中。

如果i 在字典中不是,这会将i 添加到clr 列表中。这是因为我们使用the_dic.get(i,i)。第一个i 是我们在字典中查找的key。第二个i 是“回退”值:我们在找不到键的情况下返回的值。

如果您想过滤掉这些,您可以使用:

clr = [the_dic<b>[i]</b> for i in clr <b>if i in the_dic</b>]

【讨论】:

  • map(the_dic.get, clr) 也可以代替列表推导式,尽管它不太优雅地处理错误。
  • @TemporalWolf:给定clr 中的每个元素在字典中都有一个键,是的。或者更短一点:map(the_dic.get,clr).
  • 是的,我认为在你编辑时我减少了这一点:) 我最初的建议 map(lambda x: the_dic[x], clr) 确实有一个潜在的优势,因为它会为 clr 中的无效元素抛出 KeyError...所以我可能应该离开它。无论选择哪种方法来翻译列表,这绝对是正确的方法。
【解决方案2】:
    colors = collections.defaultdict(int,{ 1:'green', 2:'yellow', 3:'black' })
    clr = [ colors[i] for i in clr ]

如果不将无关的 0 放在输出中很重要,您可以将 if 1 &lt;= i &lt;= 3 condition 添加到列表推导中。在这种情况下,您可以使用普通 dict 而不是 defaultdict。

【讨论】:

  • 谢谢,我会去收藏。
【解决方案3】:

您实际上可以在列表理解中执行此操作:

[("green"  if i == 1 else ("yellow" if i == 2 else "black")) for i in clr]

如果您想跳过不是 1、2 或 3 的值:

[("green"  if i == 1 else ("yellow" if i == 2 else "black")) for i in clr if i in range(1, 4)]

如果您想让 [1, 2, 3] 中的值保持不变,请执行以下操作:

[("green"  if i == 1 else ("yellow" if i == 2 else ("black" if i == 3 else i))) for i in clr]

【讨论】:

  • 感谢 AGN Gazer,这在我看来是做我想做的最简单的方法。
  • @SwamyYmln 这对你来说可能是最简单的,但维护起来会很糟糕。
  • @TemporalWolf 也许吧。但是这个答案解决了这个问题的标题“多个列表理解到单个列表理解”。
  • 啊,我认为这是XY Problem 的典型例子。
  • @TemporalWolf 我不同意。 simple oneliner ["green" if i == 1 else "yellow" if i == 2 else "black" for i in clr] 并不比 dict + 列表理解更难维护[尽管 dict 解决方案很优雅]。此外,这个解决方案表明,用户想要的可以通过列表理解来实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多