【问题标题】:Ternary expression in dictionary comprehension字典理解中的三元表达式
【发布时间】:2014-02-08 04:05:58
【问题描述】:

我正在尝试反转字典。在许多键具有相同值的情况下,新键(旧值)应该与一组新值(旧键)相关联。我解决了这个问题,但我正在尝试使用字典理解和一些辅助方法进行重构。

def has_unique_value(k):
    return d.values().count(d[k]) == 1

def keys_with_same_value_as_key(k):
    return set([key for key in d.keys() if d[key] == d[k]])

print( {d[k]:k if has_unique_value(k) else d[k]:keys_with_same_value_as_key(k) for k in d.keys()} )

但是,这会引发语法错误

print( {d[k]:k if has_unique_value(k) else d[k]:keys_with_same_value_as_key(k) for k in d} )
                                               ^
SyntaxError: invalid syntax

希望该代码中的对齐方式正确。它应该指向else 子句中的第二个:。知道这里有什么吗?我已经尝试了尽可能多的括号形式。

【问题讨论】:

  • 请注意,让一些值(有效)为标量而另一些为值集有点尴尬。为独特的情况设置一组值会更自然。
  • @DSM 是的,这是一个练习,并没有真正用于任何类型的生产代码。只是一个有趣的脑筋急转弯(对我来说)

标签: python dictionary list-comprehension dictionary-comprehension


【解决方案1】:

三元表达式只能应用于一个值,而不能应用于等效的字典赋值。试试这个:

{d[k]: k if has_unique_value(k) else keys_with_same_value_as_key(k) for k in d.keys()}

您的第一种方法类似于以下(不起作用):

d[k] = k if k else d[k] = None  # doesn't work

【讨论】:

  • 成功了。所以整个三元表达式实际上是评估初始d[k]:kk 部分。凉爽的!谢谢
  • @Brad Rice 没错。三元表达式正在评估在初始 d[k] 之后立即分配给该位置的值。很高兴它有帮助。
【解决方案2】:

关闭!

以下代码

d = {'a': 'x', 'b': 'y', 'c': 'x'}

def has_unique_value(k):
    return d.values().count(d[k]) == 1

def keys_with_same_value_as_key(k):
    return set([key for key in d.keys() if d[key] == d[k]])

print( {d[k]:k if has_unique_value(k) else keys_with_same_value_as_key(k) for k in d.keys()} )

生产

{'y': 'b', 'x': set(['a', 'c'])}

唯一的区别是第二个d[k]: 被删除了。


一般来说,三元表达式是这样的

a = val_if_true if test else val_if_false

不是更接近你所拥有的东西:

a = val_if_true if test else a = val_if_false

您在开始时指定三元表达式中的值应该去哪里。


RE:cmets 中的问题

这绝对是字典理解。

它基本上是在做以下事情:

m = {}
for k in d.keys():
    orig_key = k
    orig_val = d[k]

    if has_unique_value(k):
        m[orig_val] = orig_key
    else:
        m[orig_val] = keys_with_same_value_as_key(orig_key)

print m

唯一的区别是,在字典理解中,m 字典没有保存在命名空间中(我用来澄清代码的变量 orig_keyorig_val 从来不存在)。

【讨论】:

  • 所以它在技术上仍然是一个“列表”理解,那么。并没有真正处理新字典。三元表达式真的只是分配返回的新.values() 列表?
  • 当然还是字典理解。一秒钟,我将编辑我的答案以尝试详细说明。
  • 好吧,这基本上就是我的旧代码的样子。对于这样一个简单的任务来说太冗长了。所以它被称为字典理解,因为它正在构建字典,而不是列表?正如您之前所说,您不必再次指定d[k]:,因为您在最初的if 子句之前就这样做了?
  • 是的,dictionary comprehensions were added in 2.7。而且是的,d[k]: 部分“接收”整个三元表达式的输出,即k if <test> else <alternate_k>
猜你喜欢
  • 2018-09-05
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2016-12-25
  • 2017-12-24
  • 2017-09-26
相关资源
最近更新 更多