无法在没有不可迭代错误的情况下一步扩展列表并执行 set()

Cannot extend a list and take set() in a single step without Non-Iterable error

我正在尝试管理一个独特项目的列表,这些项目可能(或可能不会)在循环的每次迭代中得到添加。也许它们只是 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() 之前发生。不知道为什么不是。

有人可以解释这是为什么吗?

-罗斯

如果您愿意 uniqs 是一个集合而不是列表,您可以使用 update 遍历列表并添加任何尚不存在的元素:

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

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

您也许可以将上面的内容写成 one-liner 使用 functools.reduce:

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

尽管显式循环可能更具可读性。