【问题标题】:Cannot extend a list and take set() in a single step without Non-Iterable error无法在没有不可迭代错误的情况下一步扩展列表并获取 set()
【发布时间】:2020-12-16 14:19:16
【问题描述】:

我正在尝试管理可能(或可能不会)在循环的每次迭代中添加的唯一项目列表。也许它们只是 doSomething(someData) 产生的整数。

所以每次迭代我都会调用 doSomething 并希望将我的结果添加到不断增长的列表中......

   uniqs = []
   for md in mydata:
       newOnes = doSomething(md)                   # returns a list eg [3,2,3]
       uniqs = list(set(uniqs.extend(newOnes)))    # keep only uniquely new items

但看来我不能同时进行扩展和设置而不会出错

TypeError: 'NoneType' object is not iterable

我可以分两步完成,

   uniqs = []
   for md in mydata:
       newOnes = doSomething(md)        # returns a list eg [3,2,3]
       uniqs.extend(newOnes)            # extend the list will all new items
       uniqs = list(set(uniqs))         # keep only unique items

但我原以为那行没问题,因为 extend() 会在应用 set() 之前发生。不知道为什么不是。

有人能解释一下这是为什么吗?

-罗斯

【问题讨论】:

  • extend 返回None。您需要分两步完成。
  • 你可以使用uniqs = list(set(uniqs + newOnes))
  • 哦,当然。呃。谢谢你的笔记。
  • uniqs 不能成为集合有什么原因吗?
  • ...或者至少,不要在循环的每次迭代中在列表和集合之间来回转换

标签: python list set extend iterable


【解决方案1】:

如果您对 uniqs 是一个集合而不是一个列表感到满意,您可以使用 update 来迭代列表并添加任何尚不存在的元素:

   uniqs = set()
   for md in mydata:
       newOnes = doSomething(md)
       uniqs.update(newOnes)

如果需要,您可以将其转换为末尾带有uniqs = list(uniqs) 的列表。排序将是未定义的,但由于您已经在计算中使用集合作为中间体,因此情况已经如此。

您也许可以使用functools.reduce 将上述内容写成单行:

functools.reduce(set.union, (set(doSomething(md)) for md in mydata))

虽然显式循环可能更具可读性。

【讨论】:

    猜你喜欢
    • 2021-05-06
    • 2019-02-10
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2021-12-21
    • 2013-02-28
    相关资源
    最近更新 更多