【问题标题】:Assignment to an item of a list in single line for loop分配给单行 for 循环中的列表项
【发布时间】:2018-06-05 05:08:55
【问题描述】:

我想在单行 for 循环中对列表中的一项进行赋值。

首先我有一个列表,其中每个列表项都是字典对象。然后,我对列表的每个项目进行循环并比较字典的“nodeid”字段是否为 106。如果是,我将新字段添加到该字典中。代码如下。

K= []
K.append({'nodeid': 100 ,'elemid': 200})
K.append({'nodeid': 106 ,'elemid': 206})
K.append({'nodeid': 107 ,'elemid': 206})
for item in K: 
   if item['nodeid']==106: 
     item['S']= [2 , 124, 123 , 3532, 35]

我想将算法的循环部分写在一行中,类似于

[item['S']=12343 for item in K if item['nodeid']==106]

但是这种方法不起作用。 如何在一行中编写此循环?

谢谢

【问题讨论】:

  • 您的代码非常适合这项任务。除了练习理解之外,没有必要尝试写单行字。
  • 也许你可以有一个字典字典,而不是使用列表,由 nodeid 键控。然后你可以很容易地做到K[106]['S'] = [2 , 124, 123 , 3532, 35]。在 O(1) 时间内,不少于。

标签: python list for-loop variable-assignment


【解决方案1】:

正如我在 cmets 中所说,为这项任务编写一个单行代码并不是要走的路,因为您失去的可读性是大量

但是,如果纯粹出于好奇,您可以这样做:

K = [x if x['nodeid'] != 106 else dict(x, **{'S': [2 , 124, 123 , 3532, 35]}) for x in K]

这里的魔法发生在dict(x, **{'S': [2 , 124, 123 , 3532, 35]}),它本质上将两个dictionaries 加在一起并返回它们的结果。

【讨论】:

    【解决方案2】:

    Python 3.5+

    K = [{**d, 'S': [2 , 124, 123 , 3532, 35]} if d['nodeid'] == 106 else d for d in K]
    

    【讨论】:

    • 这比我的更优雅。 +1
    【解决方案3】:

    如果你愿意,你当然可以这样做,就像这样:

    K = []
    K.append({'nodeid': 100 ,'elemid': 200})
    K.append({'nodeid': 106 ,'elemid': 206})
    K.append({'nodeid': 107 ,'elemid': 206})
    
    K = [item if item['nodeid'] != 106 else dict(S=[2 , 124, 123 , 3532, 35], **item) for item in K]
    

    ** 是 Python 版本的“explode”或解包运算符,用于字典,详细描述 over here


    然而,考虑到nodeid,看起来您的数据已经想要在字典中了,那么为什么不这样重组它呢?

    K = {}
    K[100] = {'elemid': 200}
    K[106] = {'elemid': 206}
    K[107] = {'elemid': 206}
    
    K[106]['S'] = [2 , 124, 123 , 3532, 35]
    

    这是使用哈希/表数据结构的好处:快速方便(更不用说,可读)索引。每个元素的位置都是已知的,除非您有辅助键条件,否则您无需对包含的元素进行任何类型的迭代。

    此外,通过使用字典,您可以避免重构整个列表的成本,这通过在给出的第一个示例中使用列表推导来实现。但是请注意,如果您使用开始时的for 循环,则不会遇到该问题,因为这只会更改找到的元素,如果您在完成操作后break,则循环将完成而不会产生任何额外费用。

    【讨论】:

      【解决方案4】:

      如果你有很多项目,写一个单行意味着重建整个列表,如果你有稀疏的值要更改,这并不是很有效。

      一行代码(适用于所有版本的 python >= 2.7):

      K = [d if d['nodeid']!=106 else {k:v for k,v in list(d.items())+[('S',[2 , 124, 123 , 3532, 35])]} for d in K]
      

      如果 id 不匹配,则发出子列表,否则使用子列表 + 额外元素构建字典(不使用所有 python 版本都没有的花哨的“字典添加”)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-11
        • 2011-09-11
        • 1970-01-01
        • 2021-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多